home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / ppmtomitsu.c < prev    next >
C/C++ Source or Header  |  1993-12-07  |  18KB  |  582 lines

  1. /* ppmtomitsu.c - read a portable pixmap and produce output for the
  2. **                Mitsubishi S340-10 Thermo-Sublimation Printer
  3. **                (or the S3410-30 parallel interface)
  4. **
  5. ** Copyright (C) 1992,93 by S.Petra Zeidler
  6. ** Minor modifications by Ingo Wilken:
  7. **  - mymalloc() and check_and_rotate() functions for often used
  8. **    code fragments.  Reduces code size by a few KB.
  9. **  - use pm_error() instead of fprintf(stderr)
  10. **  - localized allocation of colorhastable
  11. **
  12. ** This software was written for the Max Planck Institut fuer Radioastronomie,
  13. ** Bonn, Germany, Optical Interferometry group
  14. **
  15. ** Permission to use, copy, modify, and distribute this software and its
  16. ** documentation for any purpose and without fee is hereby granted, provided
  17. ** that the above copyright notice appear in all copies and that both that
  18. ** copyright notice and this permission notice appear in supporting
  19. ** documentation.  This software is provided "as is" without express or
  20. ** implied warranty.
  21. */
  22.  
  23. static char SCCSid[] = "@(#)ppmtomitsu.c\t\t1.8\t(SPZ)\t3/31/93\n";
  24. #include "ppm.h"
  25. #include "ppmcmap.h"
  26. #include "pbmplus.h"
  27.  
  28. #include "mitsu.h"
  29.  
  30.  
  31. #ifdef __STDC__
  32. int main(int argc, char *argv[] )
  33. #else
  34. int main( argc, argv )
  35.     int argc;
  36.     char* argv[];
  37. #endif
  38.     {
  39.     FILE             *ifp;
  40.     /*hashinfo         colorhashtable[HASHSIZE];*/
  41.     struct hashinfo  *hashrun;
  42.     pixel            *xP;
  43.     int              argn;
  44.         int              dpi300=FALSE;
  45.     int              cols, rows, format, col, row;
  46.     int              sharpness, enlarge, copy, tiny;
  47.     pixval           maxval;
  48.     struct mediasize medias;
  49.     char             media[16];
  50.     char *usage = "[-sharpness <1-4>] [-enlarge <1-3>] [-media <a,a4,as,a4s>] [-copy <1-9>] [-tiny] [-dpi300] [ppmfile]";
  51.  
  52.     ppm_init(&argc, argv);
  53.  
  54.     argn = 1;
  55.     sharpness = 32;
  56.     enlarge   = 1;
  57.     copy      = 1;
  58.     memset(media, '\0', 16);
  59.     tiny      = FALSE;
  60.  
  61.     /* check for flags */
  62.     while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
  63.     if (pm_keymatch(argv[argn], "-sharpness", 2)) {
  64.         ++argn;
  65.         if (argn == argc || sscanf(argv[argn], "%d", &sharpness) != 1)
  66.             pm_usage(usage);
  67.         else if (sharpness < 1 || sharpness > 4)
  68.             pm_usage(usage);
  69.         }
  70.     else if (pm_keymatch(argv[argn], "-enlarge", 2)) {
  71.         ++argn;
  72.         if (argn == argc || sscanf(argv[argn], "%d", &enlarge) != 1)
  73.             pm_usage(usage);
  74.         else if (enlarge < 1 || enlarge > 3)
  75.             pm_usage(usage);
  76.         }
  77.     else if (pm_keymatch(argv[argn], "-media", 2)) {
  78.         ++argn;
  79.         if (argn == argc || sscanf(argv[argn], "%15s", media) < 1)
  80.             pm_usage(usage);
  81.         else if (mytoupper(media[0]) != 'A')
  82.             pm_usage(usage);
  83.     }
  84.     else if (pm_keymatch(argv[argn], "-copy", 2)) {
  85.         ++argn;
  86.         if (argn == argc || sscanf(argv[argn], "%d", ©) != 1)
  87.             pm_usage(usage);
  88.         else if (copy < 1 || copy > 9)
  89.             pm_usage(usage);
  90.         }
  91.     else if (pm_keymatch(argv[argn], "-dpi300", 2))
  92.         dpi300 = TRUE;
  93.     else if (pm_keymatch(argv[argn], "-tiny", 2))
  94.         tiny = TRUE;
  95.     else
  96.         pm_usage(usage);
  97.         ++argn;
  98.     }
  99.  
  100.     if (argn < argc) {
  101.         ifp = pm_openr(argv[argn]);
  102.         ++argn;
  103.     }
  104.     else
  105.         ifp = stdin;
  106.  
  107.     if (argn != argc)
  108.         pm_usage(usage);
  109.  
  110.     if (mytoupper(media[0]) == 'A')
  111.         switch (mytoupper(media[1])) {
  112.         case 'S':
  113.             medias = MSize_AS;
  114.             break;
  115.         case '4':
  116.             if(mytoupper(media[2]) == 'S')
  117.                 medias = MSize_A4S;
  118.             else {
  119.                 medias = MSize_A4;
  120.             }
  121.             break;
  122.         default:
  123.             medias = MSize_A;
  124.         }
  125.     else
  126.         medias = MSize_User;
  127.  
  128.         if (dpi300) {
  129.                 medias.maxcols *= 2;
  130.                 medias.maxrows *= 2;
  131.         }
  132.  
  133.     if (tiny) {
  134.         pixel            *pixelrow;
  135.         char             *redrow, *greenrow, *bluerow;
  136.  
  137.         ppm_readppminit(ifp, &cols, &rows, &maxval, &format);
  138.         pixelrow = (pixel *) ppm_allocrow(cols);
  139.         redrow = mymalloc(cols * sizeof(char));
  140.         greenrow = mymalloc(cols * sizeof(char));
  141.         bluerow = mymalloc(cols * sizeof(char));
  142.         lineputinit(cols, rows, sharpness, enlarge, copy, medias);
  143.  
  144.         for ( row = 0; row < rows; ++row ) {
  145.             ppm_readppmrow(ifp, pixelrow, cols, maxval, format);
  146.             switch(PPM_FORMAT_TYPE(format)) {
  147.             /* color */
  148.             case PPM_TYPE:
  149.                 for (col = 0, xP = pixelrow; col < cols; col++, xP++) {
  150.                     /* First red. */
  151.                     redrow[col] = PPM_GETR(*xP);
  152.                     /* Then green. */
  153.                     greenrow[col] = PPM_GETG(*xP);
  154.                     /* And blue. */
  155.                     bluerow[col] = PPM_GETB(*xP);
  156.                 }
  157.                 data(redrow,   cols);
  158.                 data(greenrow, cols);
  159.                 data(bluerow,  cols);
  160.                 break;
  161.             /* grayscale */
  162.             default:
  163.                 for (col = 0, xP = pixelrow; col < cols; col++, xP++)
  164.                     bluerow[col] = PPM_GETB(*xP);
  165.                 data(bluerow, cols);
  166.                 data(bluerow, cols);
  167.                 data(bluerow, cols);
  168.                 break;
  169.             }
  170.         }
  171.         pm_close(ifp);
  172.     }
  173.     else {
  174.         pixel            **pixelpic;
  175.         int              colanz, colval;
  176.         int                 i;
  177.         colorhist_vector table;
  178.  
  179.         ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
  180.         pixelpic = ppm_allocarray( cols, rows );
  181.         for (row = 0; row < rows; row++)
  182.             ppm_readppmrow( ifp, pixelpic[row], cols, maxval, format );
  183.         pm_close(ifp);
  184.  
  185.         /* first check wether we can use the lut transfer */
  186.  
  187.         table = ppm_computecolorhist(pixelpic, cols, rows, MAXLUTCOL+1, &colanz);
  188.         if (table != NULL) {
  189.             hashinfo *colorhashtable = (hashinfo *)mymalloc(HASHSIZE * sizeof(hashinfo));
  190.             for (i=0; i<HASHSIZE; i++) {
  191.                 colorhashtable[i].flag = -1;
  192.                 colorhashtable[i].next = NULL;
  193.             }
  194.  
  195.             /* we can use the lookuptable */
  196.             pm_message("found %d colors - using the lookuptable-method",colanz);
  197.             lookuptableinit(sharpness, enlarge, copy, medias);
  198.             switch(PPM_FORMAT_TYPE(format)) {
  199.             /* color */
  200.             case PPM_TYPE:
  201.                 for (colval=0; colval<colanz; colval++) {
  202.                     cmd('$');
  203.                     datum(colval);
  204.                     datum(PPM_GETR((table[colval]).color));
  205.                     datum(PPM_GETG((table[colval]).color));
  206.                     datum(PPM_GETB((table[colval]).color));
  207.  
  208.                     hashrun = &colorhashtable[myhash((table[colval]).color)];
  209.                     if (hashrun->flag == -1) {
  210.                         hashrun->color = (table[colval]).color;
  211.                         hashrun->flag  = colval;
  212.                     }
  213.                     else {
  214.                         while (hashrun->next != NULL)
  215.                             hashrun = hashrun->next;
  216.                         hashrun->next =
  217.                             (struct hashinfo *) mymalloc(sizeof(struct hashinfo));
  218.                         hashrun = hashrun->next;
  219.                         hashrun->color = (table[colval]).color;
  220.                         hashrun->flag  = colval;
  221.                         hashrun->next  = NULL;
  222.                     }
  223.                 }
  224.                 break;
  225.             /* other */
  226.             default:
  227.                 for (colval=0; colval<colanz; colval++) {
  228.                     cmd('$');
  229.                     datum(colval);
  230.                     datum(PPM_GETB((table[colval]).color));
  231.                     datum(PPM_GETB((table[colval]).color));
  232.                     datum(PPM_GETB((table[colval]).color));
  233.  
  234.                     hashrun = &colorhashtable[myhash((table[colval]).color)];
  235.                     if (hashrun->flag == -1) {
  236.                         hashrun->color = (table[colval]).color;
  237.                         hashrun->flag  = colval;
  238.                     }
  239.                     else {
  240.                         while (hashrun->next != NULL)
  241.                             hashrun = hashrun->next;
  242.                         hashrun->next =
  243.                             (struct hashinfo *) mymalloc(sizeof(struct hashinfo));
  244.                         hashrun = hashrun->next;
  245.                         hashrun->color = (table[colval]).color;
  246.                         hashrun->flag  = colval;
  247.                         hashrun->next  = NULL;
  248.                     }
  249.                 }
  250.             }
  251.             lookuptabledata(cols, rows, enlarge, medias);
  252.             for (row=0; row<rows; row++) {
  253.                 xP = pixelpic[row];
  254.                 for (col=0; col<cols; col++, xP++) {
  255.                     hashrun = &colorhashtable[myhash(*xP)];
  256.                     while (!PPM_EQUAL((hashrun->color), *xP))
  257.                         if (hashrun->next != NULL)
  258.                             hashrun = hashrun->next;
  259.                         else {
  260.                             pm_error("you just found a lethal bug.");
  261.                         }
  262.                     datum(hashrun->flag);
  263.                 }
  264.             }
  265.             free(colorhashtable);
  266.         }
  267.         else {
  268.         /* $#%@^!& no lut possible, so send the pic as 24bit */
  269.             pm_message("found too many colors for fast lookuptable mode");
  270.             frametransferinit(cols, rows, sharpness, enlarge, copy, medias);
  271.             switch(PPM_FORMAT_TYPE(format)) {
  272.             /* color */
  273.             case PPM_TYPE:
  274.                 COLORDES(RED);
  275.                 DATASTART;                    /* red coming */
  276.                 for (row=0; row<rows; row++) {
  277.                     xP = pixelpic[row];
  278.                     for (col=0; col<cols; col++, xP++)
  279.                         datum(PPM_GETR(*xP));
  280.                 }
  281.                 COLORDES(GREEN);
  282.                 DATASTART;                    /* green coming */
  283.                 for (row=0; row<rows; row++) {
  284.                     xP = pixelpic[row];
  285.                     for (col=0; col<cols; col++, xP++)
  286.                         datum(PPM_GETG(*xP));
  287.                 }
  288.                 COLORDES(BLUE);
  289.                 DATASTART;                    /* blue coming */
  290.                 for (row=0; row<rows; row++) {
  291.                     xP = pixelpic[row];
  292.                     for (col=0; col<cols; col++, xP++)
  293.                         datum(PPM_GETB(*xP));
  294.                 }
  295.                 break;
  296.             /* grayscale */
  297.             default:
  298.                 COLORDES(RED);
  299.                 DATASTART;                    /* red coming */
  300.                 for (row=0; row<rows; row++) {
  301.                     xP = pixelpic[row];
  302.                     for (col=0; col<cols; col++, xP++)
  303.                         datum(PPM_GETB(*xP));
  304.                 }
  305.                 COLORDES(GREEN);
  306.                 DATASTART;                    /* green coming */
  307.                 for (row=0; row<rows; row++) {
  308.                     xP = pixelpic[row];
  309.                     for (col=0; col<cols; col++, xP++)
  310.                         datum(PPM_GETB(*xP));
  311.                 }
  312.                 COLORDES(BLUE);
  313.                 DATASTART;                    /* blue coming */
  314.                 for (row=0; row<rows; row++) {
  315.                     xP = pixelpic[row];
  316.                     for (col=0; col<cols; col++, xP++)
  317.                         datum(PPM_GETB(*xP));
  318.                 }
  319.             }
  320.         }
  321.     }
  322.     PRINTIT;
  323.     exit(0);
  324. }
  325.  
  326. #ifdef __STDC__
  327. static void lineputinit(int cols, int rows,
  328.                         int sharpness, int enlarge, int copy,
  329.                         struct mediasize medias)
  330. #else /*__STDC__*/
  331. static int lineputinit(cols, rows, sharpness, enlarge, copy, medias)
  332.     int cols, rows;
  333.     int sharpness, enlarge, copy;
  334.     struct mediasize medias;
  335. #endif /*__STDC__*/
  336. {
  337.     ONLINE;
  338.     CLRMEM;
  339.     MEDIASIZE(medias);
  340.  
  341.     switch (enlarge) {
  342.     case 2:
  343.         HENLARGE(ENLARGEx2); /* enlarge horizontal */
  344.         VENLARGE(ENLARGEx2); /* enlarge vertical */
  345.         break;
  346.     case 3:
  347.         HENLARGE(ENLARGEx3); /* enlarge horizontal */
  348.         VENLARGE(ENLARGEx3); /* enlarge vertical */
  349.         break;
  350.     default:
  351.         HENLARGE(NOENLARGE); /* enlarge horizontal */
  352.         VENLARGE(NOENLARGE); /* enlarge vertical */
  353.     }
  354.  
  355.     COLREVERSION(DONTREVERTCOLOR);
  356.     NUMCOPY(copy);
  357.  
  358.     HOFFINCH('\000');
  359.     VOFFINCH('\000');
  360.     CENTERING(DONTCENTER);
  361.  
  362.     TRANSFERFORMAT(LINEORDER);
  363.     COLORSYSTEM(RGB);
  364.     GRAYSCALELVL(BIT_8);
  365.  
  366.     switch (sharpness) {          /* sharpness :-) */
  367.     case 0:
  368.         SHARPNESS(SP_NONE);
  369.         break;
  370.     case 1:
  371.         SHARPNESS(SP_LOW);
  372.         break;
  373.     case 2:
  374.         SHARPNESS(SP_MIDLOW);
  375.         break;
  376.     case 3:
  377.         SHARPNESS(SP_MIDHIGH);
  378.         break;
  379.     case 4:
  380.         SHARPNESS(SP_HIGH);
  381.         break;
  382.     default:
  383.         SHARPNESS(SP_USER);
  384.     }
  385.     check_and_rotate(cols, rows, enlarge, medias);
  386.     DATASTART;
  387.     return;
  388. }
  389.  
  390. #ifdef __STDC__
  391. static void lookuptableinit(int sharpness, int enlarge, int copy,
  392.                             struct mediasize medias)
  393. #else /*__STDC__*/
  394. static int lookuptableinit(sharpness, enlarge, copy, medias)
  395.     int sharpness, enlarge, copy;
  396.     struct mediasize medias;
  397. #endif /*__STDC__*/
  398. {
  399.     ONLINE;
  400.     CLRMEM;
  401.     MEDIASIZE(medias);
  402.  
  403.     switch (enlarge) {
  404.     case 2:
  405.         HENLARGE(ENLARGEx2); /* enlarge horizontal */
  406.         VENLARGE(ENLARGEx2); /* enlarge vertical */
  407.         break;
  408.     case 3:
  409.         HENLARGE(ENLARGEx3); /* enlarge horizontal */
  410.         VENLARGE(ENLARGEx3); /* enlarge vertical */
  411.         break;
  412.     default:
  413.         HENLARGE(NOENLARGE); /* enlarge horizontal */
  414.         VENLARGE(NOENLARGE); /* enlarge vertical */
  415.     }
  416.  
  417.     COLREVERSION(DONTREVERTCOLOR);
  418.     NUMCOPY(copy);
  419.  
  420.     HOFFINCH('\000');
  421.     VOFFINCH('\000');
  422.     CENTERING(DONTCENTER);
  423.  
  424.     TRANSFERFORMAT(LOOKUPTABLE);
  425.  
  426.     switch (sharpness) {          /* sharpness :-) */
  427.     case 0:
  428.         SHARPNESS(SP_NONE);
  429.         break;
  430.     case 1:
  431.         SHARPNESS(SP_LOW);
  432.         break;
  433.     case 2:
  434.         SHARPNESS(SP_MIDLOW);
  435.         break;
  436.     case 3:
  437.         SHARPNESS(SP_MIDHIGH);
  438.         break;
  439.     case 4:
  440.         SHARPNESS(SP_HIGH);
  441.         break;
  442.     default:
  443.         SHARPNESS(SP_USER);
  444.     }
  445.  
  446.     LOADLOOKUPTABLE;
  447.     return;
  448. }
  449.  
  450. #ifdef __STDC__
  451. static void lookuptabledata(int cols, int rows, int enlarge,
  452.                                                         struct mediasize medias)
  453. #else /*__STDC__*/
  454. static int lookuptabledata(cols, rows, enlarge, medias)
  455.     int   rows, cols;
  456.     int   enlarge;
  457.     struct mediasize medias;
  458. #endif /*__STDC__*/
  459. {
  460.     DONELOOKUPTABLE;
  461.     check_and_rotate(cols, rows, enlarge, medias);
  462.     DATASTART;
  463.     return;
  464. }
  465.  
  466. #ifdef __STDC__
  467. static void frametransferinit(int cols, int rows, int sharpness,
  468.                               int enlarge, int copy, struct mediasize medias)
  469. #else
  470. static int frametransferinit(cols, rows, sharpness, enlarge, copy, medias)
  471.  
  472.     int     rows, cols;
  473.     int     sharpness, enlarge, copy;
  474.     struct mediasize medias;
  475. #endif
  476. {
  477.     ONLINE;
  478.     CLRMEM;
  479.     MEDIASIZE(medias);
  480.  
  481.     switch (enlarge) {
  482.     case 2:
  483.         HENLARGE(ENLARGEx2); /* enlarge horizontal */
  484.         VENLARGE(ENLARGEx2); /* enlarge vertical */
  485.         break;
  486.     case 3:
  487.         HENLARGE(ENLARGEx3); /* enlarge horizontal */
  488.         VENLARGE(ENLARGEx3); /* enlarge vertical */
  489.         break;
  490.     default:
  491.         HENLARGE(NOENLARGE); /* enlarge horizontal */
  492.         VENLARGE(NOENLARGE); /* enlarge vertical */
  493.     }
  494.  
  495.     COLREVERSION(DONTREVERTCOLOR);
  496.     NUMCOPY(copy);
  497.  
  498.     HOFFINCH('\000');
  499.     VOFFINCH('\000');
  500.     CENTERING(DONTCENTER);
  501.  
  502.     TRANSFERFORMAT(FRAMEORDER);
  503.     COLORSYSTEM(RGB);
  504.     GRAYSCALELVL(BIT_8);
  505.  
  506.     switch (sharpness) {          /* sharpness :-) */
  507.     case 0:
  508.         SHARPNESS(SP_NONE);
  509.         break;
  510.     case 1:
  511.         SHARPNESS(SP_LOW);
  512.         break;
  513.     case 2:
  514.         SHARPNESS(SP_MIDLOW);
  515.         break;
  516.     case 3:
  517.         SHARPNESS(SP_MIDHIGH);
  518.         break;
  519.     case 4:
  520.         SHARPNESS(SP_HIGH);
  521.         break;
  522.     default:
  523.         SHARPNESS(SP_USER);
  524.     }
  525.     check_and_rotate(cols, rows, enlarge, medias);
  526.     return;
  527. }
  528.  
  529.  
  530. #ifdef __STDC__
  531. static void *
  532. mymalloc(long bytes)
  533. #else
  534. static char *
  535. mymalloc(bytes)
  536.     long bytes;
  537. #endif
  538. {
  539.     void *mem;
  540.  
  541.     mem = malloc(bytes);
  542.     if( mem == NULL )
  543.         pm_error("out of memory allocating %d bytes", bytes);
  544.  
  545.     return mem;
  546. }
  547.  
  548.  
  549. #ifdef __STDC__
  550. static void
  551. check_and_rotate(int cols, int rows, int enlarge, struct mediasize medias)
  552. #else
  553. static int
  554. check_and_rotate(cols, rows, enlarge, medias)
  555.     int cols, rows, enlarge;
  556.     struct mediasize medias;
  557. #endif
  558. {
  559.     if (cols > rows) {
  560.         ROTATEIMG(DOROTATE);                        /* rotate image */
  561.         if (enlarge*rows > medias.maxcols || enlarge*cols > medias.maxrows) {
  562.             pm_error("Image too large, MaxPixels = %d x %d", medias.maxrows, medias.maxcols);
  563.         }
  564.         HPIXELS(cols);
  565.         VPIXELS(rows);
  566.         HPIXELSOFF((medias.maxcols/enlarge - rows)/2);
  567.         VPIXELSOFF((medias.maxrows/enlarge - cols)/2);
  568.         pm_message("rotating image for output");
  569.     }
  570.     else {
  571.         ROTATEIMG(DONTROTATE);
  572.         if (enlarge*rows > medias.maxrows || enlarge*cols > medias.maxcols) {
  573.             pm_error("Image too large, MaxPixels = %d x %d", medias.maxrows, medias.maxcols);
  574.         }
  575.         HPIXELS(cols);
  576.         VPIXELS(rows);
  577.         HPIXELSOFF((medias.maxcols/enlarge - cols)/2);
  578.         VPIXELSOFF((medias.maxrows/enlarge - rows)/2);
  579.     }
  580. }
  581.  
  582.