home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gle / gle / dvitobit.c < prev    next >
C/C++ Source or Header  |  1992-11-29  |  15KB  |  655 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <math.h>
  7. #ifdef __TURBOC__
  8. extern unsigned _stklen=20000;
  9. #include <alloc.h>
  10. #else
  11. #define huge
  12. #endif
  13.  
  14. #define true (!false)
  15. #define false 0
  16. #include "bmp.h"
  17. #include "dvipath.h"
  18.  
  19. double d_xscale, d_yscale;
  20. int gdebug=false;
  21. int fittobit;    /* true if picture should be scaled up to fit bitmap, wp-tiff */
  22.  
  23. #define scx(v) ( ((v) * d_xscale + 1))
  24. #define scy(v) ( ((v) * d_yscale + 1))
  25. #define dbg if (gdebug)
  26.  
  27. char *bgidir();
  28. int path_bezier(int  x1, int  y1, int  x2, int  y2, int  x3, int  y3);
  29. int path_alloc(void);
  30. int path_move(int  x1, int  y1);
  31. int path_line(int  x1, int  y1);
  32. int path_closepath(void);
  33.  
  34. int dev_print(Bitmap *b);
  35. int dev_size(int *nxbits, int *nybits, double *devxcm, double *devycm);
  36. int dev_hpplus;
  37. int dev_hires;
  38. int dev_noff;
  39. int dev_noclip;
  40. int dev_nosquash;
  41. int dev_wide;
  42. double devxcm,devycm;
  43. double uxcm,uycm;
  44.  
  45. Bitmap *bb;
  46. /*---------------------------------------------------------------------------*/
  47. /*        Local stuff */
  48. int flipit;
  49. FILE *outbit;
  50. FILE *inf;
  51. /*---------------------------------------------------------------------------*/
  52. main_usage()
  53. {
  54.     printf("Usage: dviprint [-depson | -dlj] [-old] [-hires] [-debug] [-output xx.prt]\n");
  55.     printf("    -depson   To produce output for epson printers \n");
  56.     printf("    -dwp      To add tiff image to wp .eps file \n");
  57.     printf("    -dlj      To produce output for HP LaserJet printers \n");
  58.     printf("    -dpj      To produce output for HP PaintJet printers \n");
  59.     printf("    -dvt      To print bitmap to screen (preview) \n");
  60.     printf("    -over     Overhead transparency mode for PaintJet\n");
  61.     printf("    -old      For old HP Laser Jet printers (no compression)\n");
  62.     printf("     -hires      Uses high resolution for that printer (slower)\n");
  63.     printf("     -wide     If your printer has a wide carriage \n");
  64.     printf("     -noflip   Disable's auto flipping \n");
  65.     printf("     -flip     Forces flip  \n");
  66.     printf("     -nosquash Tries to print it full size\n");
  67.     printf("     -compress Force internal bitmap compression (slow) \n");
  68.     printf("     -noff     No form feed\n");
  69.     printf("     -debug    Prints debug messages\n");
  70.     printf("     -out x.x  Prints output to file instead of printer port\n");
  71.     printf("\n");
  72. }
  73. enum {D_EPSON=1,D_LJ,D_VT,D_PJ,D_WP};
  74. int dev_type,dev_noflip,dev_lowmem,dev_low,dev_over,dev_flip;
  75. int bmp_compress;
  76. char outbitname[80];
  77. char gleroot[90];
  78. main(int argc, char **argv)
  79. {
  80.     int i;
  81.     char *ss;
  82.     strcpy(gleroot,argv[0]);
  83. #ifdef __TURBOC__
  84.     ss = strchr(gleroot,'\\');
  85.     if (ss==NULL) printf("Unable to locate files AGRV[0] wrong");
  86.     for (;strchr(ss+1,'\\')!=NULL;) ss = strchr(ss+1,'\\');
  87.     *(ss+1) = 0;
  88. #endif
  89.  
  90.     if (argc<=1) { main_usage(); exit(0);}
  91.  
  92.     inf = fopen("out.dvi","rb");
  93.     if (inf==NULL) {
  94.         printf("Unable to open OUT.DVI for input, run DVIGLE first\n");
  95.         gle_abort("");
  96.     }
  97.  
  98.     dev_hpplus = true;
  99.     for (i=1;i<argc; i++) {
  100. #ifdef __TURBOC__
  101.         strlwr(argv[i]);
  102. #endif
  103.         if (strncmp(argv[i],"/o",2)==0) dev_hpplus = false;
  104.         else if (strncmp(argv[i],"/h",2)==0) dev_hires = true;
  105.         else if (strncmp(argv[i],"-ol",3)==0) dev_hpplus = false;
  106.         else if (strncmp(argv[i],"-ov",3)==0) dev_over = true;
  107.         else if (strncmp(argv[i],"-me",3)==0) dev_lowmem = false;
  108.         else if (strncmp(argv[i],"-co",3)==0) bmp_compress = true;
  109.         else if (strncmp(argv[i],"-lo",3)==0) dev_low = true;
  110.         else if (strncmp(argv[i],"-h",2)==0) dev_hires = true;
  111.         else if (strncmp(argv[i],"-nosq",5)==0) dev_nosquash = true;
  112.         else if (strncmp(argv[i],"-wi",3)==0) dev_wide = true;
  113.         else if (strncmp(argv[i],"-noff",5)==0) dev_noff = true;
  114.         else if (strncmp(argv[i],"-nocl",5)==0) dev_noclip = true;
  115.         else if (strncmp(argv[i],"-n",2)==0) dev_noflip = true;
  116.         else if (strncmp(argv[i],"-fl",3)==0) dev_flip = true;
  117.         else if (strncmp(argv[i],"-deb",4)==0) gdebug = true;
  118.         else if (strncmp(argv[i],"-dwp",4)==0) dev_type = D_WP;
  119.         else if (strncmp(argv[i],"-dep",4)==0) dev_type = D_EPSON;
  120.         else if (strncmp(argv[i],"-dl",3)==0) dev_type = D_LJ;
  121.         else if (strncmp(argv[i],"-dv",3)==0) dev_type = D_VT;
  122.         else if (strncmp(argv[i],"-dp",3)==0) dev_type = D_PJ;
  123.         else if (strncmp(argv[i],"-o",2)==0) {
  124.             strcpy(outbitname,argv[++i]);
  125.         }
  126.         else {
  127.             printf("Unrecognised qualifier, {%s} \n",argv[i]);
  128.             main_usage();
  129.             exit(0);
  130.         }
  131.     }
  132.     if (dev_type==0) { main_usage(); exit(0);}
  133.     if (dev_type==D_WP) {
  134.       if (strcmp(outbitname,"out.dvi")==0) {
  135.         printf("Must specify name of .eps file to add tiff too.\n");
  136.         exit(0);
  137.       }
  138.       if (strstr(outbitname,".")!=0) {
  139.         * strchr(outbitname,'.') = 0;
  140.       }
  141.       strcat(outbitname,".epf");
  142.     }
  143.     if (strstr(outbitname,".gle")!=0) {
  144.         printf("Will not erase a .gle file\n");
  145.         exit(0);
  146.     }
  147.     open_outbit(outbitname);
  148.     draw_file();
  149.     close_output();
  150. }
  151. /*---------------------------------------------------------------------------*/
  152. open_outbit(char *outbitname)
  153. {
  154. #if __TURBOC__
  155.     if (strlen(outbitname)!=0) {
  156.       printf("Writing output to file {%s} \n",outbitname);
  157.       outbit = fopen(outbitname,"wb");
  158.       if (outbit==NULL) {
  159.         printf("Could not open that FILE for output {%s} \n",outbitname);
  160.         perror("");
  161.         exit(1);
  162.       }
  163.     } else     printf("Printing to LPT1 \n");
  164. #else
  165.  
  166.         /* Special binary open for VMS */
  167. /*    strcpy(outbitname,"out.prt"); */
  168.     printf("Writing output to file {%s} \n",outbitname);
  169. #ifdef unix
  170.     if ((outbit = fopen(outbitname,"wb")) == NULL)
  171. #else
  172.     if ((outbit = fopen (outbitname,"wb","rfm=fix","bls=512","mrs=512")) == NULL)
  173. #endif
  174.     {   printf ("Can't open output bitmap file.\n");
  175.             abort();
  176.         }
  177. #endif
  178. }
  179. /*---------------------------------------------------------------------------*/
  180. /*   Path variables for bitmap */
  181. int *path;
  182. int npath;
  183. int npath_alloc;
  184.  
  185. int file_end = false;
  186. float getf(void);
  187. int getfxy(int *x, int *y);
  188. getfxy(int *x, int  *y)
  189. {
  190.     float u,xx,yy;
  191.     xx = getf();
  192.     yy = getf();
  193.     if (flipit) {
  194.         u = yy;
  195.         yy = uxcm - xx;
  196.         xx = u;
  197.     }
  198.     /*printf("fxy %g %g \n",xx,yy); */
  199.     *x = (int) .5+scx(xx);
  200.     *y = (int) .5+scy(yy);
  201. }
  202. float getf(void)
  203. {
  204.     static float x;
  205.     fread(&x,sizeof(x),1,inf);
  206.     if (feof(inf)) file_end = true;
  207.     return x;
  208. }
  209. long getl(void)
  210. {
  211.     static long x;
  212.     fread(&x,sizeof(x),1,inf);
  213.     if (feof(inf)) file_end = true;
  214.     return x;
  215. }
  216.  
  217.  
  218. float cur_lwidth,cur_color,cur_fill,cur_dashlen;
  219. long cur_lstyle;
  220.  
  221. draw_file(void)
  222. {
  223.     int x2,y2,x3,y3,sx,sy;
  224.     int x,y,cx,cy;
  225.     int g=0;
  226.     float fx,fy;
  227.     int i,dot;
  228.  
  229.     for (;!file_end;) {
  230.       i = getl();
  231.       if (file_end) break;
  232.       switch (i) {
  233.         case p_size:
  234.             dbg printf("#size \n");
  235.             fx = getf(); fy = getf();
  236.             d_open(fx,fy);
  237.             dbg printf(":");
  238.         case p_newpath:
  239.             dbg printf("#newpath \n");
  240.             npath = 0;
  241.             break;
  242.         case p_move:
  243.             getfxy(&x,&y);
  244.             cx = x; cy = y;
  245.             dbg printf("#move (%d) %d %d  \n",npath,x,y);
  246.             path_move(x,y);
  247.             sx = cx; sy = cy;
  248.             break;
  249.         case p_line:
  250.             dbg {g++; if (g>200) {printf(":"); g=0;}}
  251.             getfxy(&x,&y);
  252.             cx = x; cy = y;
  253.             dbg printf("#line (%d) %d %d  \n",npath,x,y);
  254.             path_line(x,y);
  255.             break;
  256.         case p_closepath:
  257.             dbg printf("#closepath %d %d \n",sx,sy);
  258.             path_closepath();
  259.             cx = sx; cy = sy;
  260.             break;
  261.         case p_dline:
  262.             dbg {g++; if (g>200) {printf(":"); g=0;}}
  263.             getfxy(&x,&y);
  264.             bmp_line(bb,cx,cy,x,y);
  265.             npath = 0;
  266.             dbg printf("#(nopath)line %d %d %d %d  \n",cx,cy,x,y);
  267.             cx = x; cy = y;
  268.             break;
  269.         case p_bezier:
  270.             getfxy(&x,&y);
  271.             getfxy(&x2,&y2);
  272.             getfxy(&x3,&y3);
  273.             path_bezier(x,y,x2,y2,x3,y3);
  274.             dbg printf("#bezier (%d)\n",npath);
  275.             cx = x3; cy = y3;
  276.             break;
  277.         case p_stroke:
  278.             dbg printf("#stroke \n");
  279.             path_stroke();
  280.             break;
  281.         case p_fill:
  282.             dbg printf("#fill \n");
  283.             path_fill();
  284.             break;
  285.         case p_lwidth:
  286.             dbg printf("#lwidth \n");
  287.             cur_lwidth = getf();
  288.             bmp_lwidth(bb,(int) scx(cur_lwidth));
  289.             break;
  290.         case p_dashlen:
  291.             dbg printf("#dashlen \n");
  292.             cur_dashlen = getf();
  293.                         dot=(int)(0.5+d_yscale*cur_dashlen);
  294.                         dot = dot > 0 ? dot : 1;
  295.             bmp_lstyle(bb,cur_lstyle,dot);
  296.             break;
  297.         case p_lstyle:
  298.             dbg printf("#lstyle \n");
  299.             cur_lstyle = getl();
  300.                         dot=(int)(0.5+d_yscale*cur_dashlen);
  301.                         dot = dot > 0 ? dot : 1;
  302.             bmp_lstyle(bb,cur_lstyle,dot);
  303.             break;
  304.         case p_setcolor:
  305.             x = getl(); x2 = getl(); x3 = getl(); y = getl();
  306.             dbg printf("#setcolor %d %d %d f=%d \n",x,x2,x3,y);
  307.             bmp_setcolor(bb,x,x2,x3,y); /* r,g,b,f */
  308.             break;
  309.         case p_clip:
  310.             dbg printf("#clipcurpath \n");
  311.             path_clip();
  312.             break;
  313.         case p_saveclip:
  314.             dbg printf("#save clip \n");
  315.             bmp_saveclip(bb);
  316.             break;
  317.         case p_restoreclip:
  318.             dbg printf("#restore clip \n");
  319.             bmp_restoreclip(bb);
  320.             break;
  321.         case p_null:
  322.             dbg printf("Null \n");
  323.             break;
  324.         default:
  325.             printf("Error in PATH codes in .DVI file %d\n",i);
  326.             break;
  327.       }
  328.     }
  329.     d_close();
  330. }
  331. gle_abort(char *s)
  332. {
  333.     printf("%s",s);
  334.     exit(1);
  335. }
  336. path_send()
  337. {
  338.     int sx=0,sy=0,cx=0,cy=0,x1,y1,x2,y2,x3,y3;
  339.     int closed=true;
  340.     int i,j,p1,p2;
  341.  
  342.     bmp_newpath(bb);
  343.     for (i=0;i<npath;i++) {
  344.       switch(path[i]) {
  345.         case p_move:
  346.         sx = path[++i];
  347.         sy = path[++i];
  348.         bmp_pmove(bb,sx,sy);
  349.         cx = sx; cy = sy;
  350.         break;
  351.         case p_line:
  352.         x1 = path[++i];
  353.         y1 = path[++i];
  354.         dbg printf("pline %d %d \n",x1,y1);
  355.         bmp_pline(bb,x1,y1);
  356.         cx = x1; cy = y1;
  357.         break;
  358.         case p_bezier:
  359.         x1 = path[++i];  y1 = path[++i];
  360.         x2 = path[++i];  y2 = path[++i];
  361.         x3 = path[++i];  y3 = path[++i];
  362.         dbg printf("pbezier %d %d   %d %d   %d %d\n",x1,y1,x2,y2,x3,y3);
  363.         bmp_pbezier(bb,cx,cy,x1,y1,x2,y2,x3,y3);
  364.         cx = x3; cy = y3;
  365.         break;
  366.         case p_closepath:
  367.         dbg if (cx!=sx || cy!=sy) printf("pclosepath %d %d \n",sx,sy);
  368.         if (cx!=sx || cy!=sy) bmp_pline(bb,sx,sy);
  369.         cx = sx; cy = sy;
  370.         break;
  371.         default:
  372.         printf("Error in path_fill code path[%d] %d \n",i,path[i]);
  373.       }
  374.     }
  375. }
  376. path_fill(void)
  377. {
  378.     path_send();
  379.     bmp_fill(bb);
  380. }
  381. path_clip(void)
  382. {
  383.     path_send();
  384.     bmp_clip(bb);
  385. }
  386. path_stroke(void)
  387. {
  388.     int sx=0,sy=0,cx=0,cy=0,x1,y1,x2,y2,x3,y3;
  389.     int closed=true;
  390.     int i,j,p1,p2;
  391.  
  392.     bmp_newpath(bb);
  393.     for (i=0;i<npath;i++) {
  394.       switch(path[i]) {
  395.         case p_move:
  396.         sx = path[++i];
  397.         sy = path[++i];
  398.         cx = sx; cy = sy;
  399.         break;
  400.         case p_line:
  401.         x1 = path[++i];
  402.         y1 = path[++i];
  403.         bmp_line(bb,cx,cy,x1,y1);
  404.         cx = x1; cy = y1;
  405.         break;
  406.         case p_bezier:
  407.         x1 = path[++i];  y1 = path[++i];
  408.         x2 = path[++i];  y2 = path[++i];
  409.         x3 = path[++i];  y3 = path[++i];
  410.         bmp_bezier(bb,cx,cy,x1,y1,x2,y2,x3,y3);
  411.         cx = x3; cy = y3;
  412.         break;
  413.         case p_closepath:
  414.         if (cx!=sx || cy!=sy) bmp_line(bb,cx,cy,sx,sy);
  415.         cx = sx; cy = sy;
  416.         break;
  417.         default:
  418.         printf("Error in path_fill code path[%d] %d \n",i,path[i]);
  419.       }
  420.     }
  421. }
  422. path_move(int  x,int y)
  423. {
  424.     path_alloc();
  425.     path[npath++] = p_move;
  426.     path[npath++] = x;
  427.     path[npath++] = y;
  428. }
  429. path_line(int x,int y)
  430. {
  431.     path_alloc();
  432.     path[npath++] = p_line;
  433.     path[npath++] = x;
  434.     path[npath++] = y;
  435. }
  436. path_bezier(int x1, int y1, int x2, int y2,int x3, int y3)
  437. {
  438.     path_alloc();
  439.     path[npath++] = p_bezier;
  440.     path[npath++] = x1;    path[npath++] = y1;
  441.     path[npath++] = x2;    path[npath++] = y2;
  442.     path[npath++] = x3;    path[npath++] = y3;
  443. }
  444. path_closepath()
  445. {
  446.     path_alloc();
  447.     path[npath++] = p_closepath;
  448. }
  449. path_alloc(void)
  450. {
  451.     static int npa;
  452.     int *a;
  453.  
  454.     if (npath < (npath_alloc-10)) return;
  455.     npath_alloc = 20 + 2 * npath;
  456.     if (npath_alloc<300) npath_alloc = 300;
  457.     dbg  printf("=== Allocate %d %d \n",npath_alloc,npath);
  458.     a = (int *) calloc(1,npath_alloc*sizeof(int));
  459.     if (a==NULL) {
  460.         gle_abort("Unable to allocate memory for path \n");
  461.     }
  462.     if (path != NULL) {
  463.         dbg printf("path reallocate, copy \n");
  464.         memcpy(a,path,(npa)*sizeof(int));
  465.         free(path);
  466.     }
  467.     npa = npath_alloc;
  468.     path = a;
  469. }
  470. path_free(void)
  471. {
  472.     if (path==NULL) return;
  473.     free(path);
  474.     path = NULL;
  475.     npath = 0;
  476.     npath_alloc = 0;
  477. }
  478.  
  479. d_open(double width, double height)
  480. {
  481.     double f,f1,f2,fx,fy;
  482.     double d_scale;
  483.     int nxbits,nybits;
  484.  
  485.     {devxcm = width; devycm = height;}
  486.     if (!dev_noflip &&  width>height &&!dev_wide) {devxcm = height; devycm = width;}
  487.     switch (dev_type) {
  488.       case D_EPSON:
  489.         dev_size_ep(&nxbits, &nybits, &devxcm, &devycm);
  490.         break;
  491.       case D_WP:
  492.         dev_size_wp(&nxbits, &nybits, &devxcm, &devycm);
  493.         break;
  494.       case D_LJ:
  495.         dev_size_lj(&nxbits, &nybits, &devxcm, &devycm);
  496.         break;
  497.       case D_VT:
  498.         dev_size_vt(&nxbits, &nybits, &devxcm, &devycm);
  499.         break;
  500.       case D_PJ:
  501.         dev_size_pj(&nxbits, &nybits, &devxcm, &devycm);
  502.         break;
  503.     }
  504.     uxcm = width; uycm = height;
  505.  
  506.     d_scale = devxcm / width;
  507.     f = devycm / height;
  508.     if (f<d_scale) d_scale = f;
  509.  
  510.     if (fittobit) {
  511.         fx = devxcm / width;
  512.         d_scale = 1;
  513.         fy = devycm / height;
  514.     }
  515.     if (d_scale<.98) {
  516.         if ( dev_flip
  517.         || (dev_wide && !dev_noflip && height>width )
  518.         ||   ( !dev_wide && width>height && !dev_noflip)
  519.         ) {
  520.             d_scale = devycm/width;
  521.             f = devxcm/height;
  522.             if (f<d_scale) d_scale = f;
  523.             flipit = true;
  524.             printf("Flipping graph to fit on page better \n");
  525.         }
  526.     }
  527.  
  528.     /* Get correct size of drawing */
  529.     if (d_scale > 1.001) d_scale = 1;
  530.     else {
  531.         if (d_scale < .99) printf("Squashing onto page by factor %g \n",d_scale);
  532.     }
  533.  
  534.     d_xscale = d_scale * (nxbits-2) / devxcm; /* Device Scale X, Device Scale y */
  535.     d_yscale = d_scale * (nybits-2) / devycm;
  536.     if (fittobit) {
  537.         d_xscale = fx * (nxbits-2) / devxcm;
  538.         d_yscale = fy * (nybits-2) / devycm;
  539.     }
  540.     bb = bmp_open(nxbits,nybits,1,bmp_compress);
  541.     if (bb==NULL) gle_abort("Unable to create bitmap\n");
  542. }
  543. /*---------------------------------------------------------------------------*/
  544. d_close()
  545. {
  546.     path_free();
  547.     printf("Bitmap image created.\n");
  548.     switch (dev_type) {
  549.       case D_EPSON:
  550.         dev_print_ep(bb);
  551.         break;
  552.       case D_WP:
  553.         dev_print_wp(bb);
  554.         break;
  555.       case D_LJ:
  556.         dev_print_lj(bb);
  557.         break;
  558.       case D_PJ:
  559.         dev_print_pj(bb);
  560.         break;
  561.       case D_VT:
  562.         dev_print_vt(bb);
  563.         break;
  564.     }
  565.     bmp_close(bb);
  566. }
  567.  
  568. #ifdef __TURBOC__
  569. #include <dos.h>
  570. char put_out(char c);
  571. int status(void);
  572. status(void)
  573. {
  574.     union REGS reg;
  575.  
  576.     reg.h.ah = 2;
  577.     reg.x.dx = 0;
  578.     int86(0x17, ®, ®);
  579.     return (reg.h.ah & 0x80);
  580. }
  581. char put_out(char c)
  582. {
  583.     union REGS reg;
  584.     int w=0;
  585.     static int ft=0;
  586.  
  587.     if (outbit!=NULL) {
  588.         fputc(c,outbit);
  589.         return;
  590.     }
  591.     while (!status()) {
  592.         w++;
  593.         if (w>10000) if (ft==0) {printf("Printer Busy\n"); w=0; ft=1;}
  594.         if (w>10000) {printf(".");  w=0;}
  595.     }
  596.     /* if (ft==1) printf("\n"); */
  597.     reg.h.ah = 0;
  598.     reg.h.al = c;
  599.     reg.x.dx = 0;
  600.     int86(0x17,®,®);
  601.     return (reg.h.ah);
  602. }
  603. close_output()
  604. {
  605.     if (outbit!=NULL) fclose(outbit);
  606. }
  607.  
  608. #else
  609.  
  610. #include <stdio.h>
  611. #ifdef VAXC
  612. #include <file.h>
  613. #endif
  614. char zzbuff[512];
  615. int nzz=0;
  616. put_out(char c)
  617. {
  618.     zzbuff[nzz++] = c;
  619.     if (nzz==512) {
  620.         fwrite(zzbuff,nzz,1,outbit);
  621.         nzz = 0;
  622.     }
  623. }
  624. close_output()
  625. {
  626.     if (nzz > 0)  { /* for vax, must send whole blocks */
  627.         memset(zzbuff+nzz,0,512-nzz);
  628.         fwrite(zzbuff,512,1,outbit);
  629.     }
  630.     fclose(outbit);
  631. }
  632.  
  633. #endif
  634. printmem(char *s, int n)
  635. {
  636.     for (;n>0;n--) put_out(*s++);
  637. }
  638.  
  639. char *bgidir()
  640. {
  641. #ifdef __TURBOC__
  642.     char *s;
  643.     static char xx[80];
  644.     s = getenv("GLE_BGI");
  645.     if (s==NULL) {
  646.         strcpy(xx,gleroot);
  647.         strcat(xx,"exe\\");
  648.         s = xx;
  649.     }
  650.     return s;
  651. #endif
  652. }
  653.  
  654.  
  655.