10a2b055274d295c986dd29ce0663f8fdfc66db9
[evolisprinter.git] / cupsevolis.c
1 /*
2  *
3  * Contents:
4  *
5  *   Setup()        - Prepare the printer for printing.
6  *   StartPage()    - Start a page of graphics.
7  *   EndPage()      - Finish a page of graphics.
8  *   Shutdown()     - Shutdown the printer.
9  *   CompressData() - Compress a line of graphics.
10  *   main()         - Main entry and processing of driver.
11  */
12
13 #include <string.h>
14 #include <stdlib.h>
15 #include <sys/stat.h>
16 #include <signal.h>
17 #include <ctype.h>
18 #include <fcntl.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include "evolis.h"
22 #include "evoliserror.h"
23 #include "cups.h"
24 #include "ppd.h"
25 #include "raster.h"
26
27 #define LVERSION "3.02 RC12"
28
29 #define EVOLIS_1  0
30 #define CUPS15    1
31
32 #define PORTRAIT    1
33 #define LANDSCAPE   2 
34
35 #define MAX_MAG_DATA 256
36 #define MAX_PASSTHROUGH_SZ 2048
37
38 // ----------------------------------------------------
39 // Typedefs
40 // ----------------------------------------------------
41
42 typedef struct TrackInfo_tag {
43     int type;                   // MAGTYPE_ISO1, MAGTYPE_ISO2, MAGTYPE_ISO3, MAGTYPE_SIPASS, MAGTYPE_C2_75, MAGTYPE_JIS2, MAGTYPE_C4, MAGTYPE_C2_210
44     int density;                // 0:auto / 75 / 210
45     char data[MAX_MAG_DATA];
46 } TrackInfo_t;
47
48 typedef struct MagInfo_tag {
49     TrackInfo_t Track[3];
50     int KeepCard;               // 1 true 0 false
51     char Coercivity[5];         // HICO, LOCO, JIS, NONE
52 } MagInfo_t; 
53
54 typedef struct LamOption_tag {
55     char    defLam;                 /* Param 1 de PLm  : 0, r, v, b     */
56     char    exitLam;                /* Param 2 de PLm  : 0, r, v        */              
57     int     lamType;                /* Param 2 de PLds : 0, 1, 2        */              
58     int     lamSpeed;               /* Param 3 de PLds : 2-18           */
59     int     lamTemp;                /* Param 4 de PLds : 100-180        */
60     int     lamAlt;                 /* Param 5 de PLds : 0,1,2          */      
61     char    lamDesc[17];            /* Param 6 de PLds : description    */
62 } LaminatorOption_t;
63
64 // ----------------------------------------------------
65 // Globals
66 // ----------------------------------------------------
67
68 MagInfo_t MagInfoCard;
69 LaminatorOption_t LamInfo;
70
71 char InkType[10];
72 char BlackIn[2];
73 char ColorSmooth[15];
74 char Soften[10];
75 char EjectCard[10];
76
77 static  int     page            = 0;              
78 static  int     cOrientation    = 0;
79 static  int     cSides          = 0;
80 static  int     tMargin         = 0;
81 static  int     lMargin         = 0;    
82 static  int     rMargin         = 0;
83 static  int     bMargin         = 0;
84
85 int Brightness[2], Contrast[2], SensibilityK[2], QualityK, SensibilityO[2];
86 int DetectAuto, StartDist;
87 int overlayRegion[2][8];
88
89 // ----------------------------------------------------
90 // Prototypes
91 // ----------------------------------------------------
92
93 // --- standard cups functions 
94
95 void            Setup                   ( void );
96 void            StartPage               ( const ppd_file_t * ppd, const cups_page_header_t * header, cups_raster_t * ras );
97 void            EndPage                 ( const cups_page_header_t * header );
98 void            Shutdown                ( void );
99 void            CancelJob               ( int sig );
100
101 // --- option management 
102
103 int             myGetIntOption          ( char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, int defaultValue );
104 char*           myGetStrOption          ( char *dest, char* optionName, int num_options, cups_option_t *options,    
105                                                                                                 ppd_file_t *ppd, const char* defaultStr );
106 char            myGetCharOption         ( char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, char defaultValue );
107 int             GetLaminationOption     ( LaminatorOption_t *lam_opt, int num_options, cups_option_t *options, ppd_file_t *ppd );
108 int             GetMagOption            ( MagInfo_t *mag, int num_options, cups_option_t *options, ppd_file_t *ppd );
109 int             GetPageSetupOption      ( int num_options, cups_option_t *options, ppd_file_t *ppd );
110 int             GetEvolisOption         ( int num_options, cups_option_t *options, ppd_file_t *ppd );
111 int             SendMagEncodingHeader   ( MagInfo_t* mag );
112 int             EvolisModelNumberFromPPD( char*  modelname );
113 int             ProcessSpecialCommands  ( const char* cmd, MagInfo_t* mag );
114 int             SetOverlayRegion        (  int region[8] );
115
116 // --- dsp
117  
118 static  void    ShareRVBtoMem           ( long Height, long Width, long WidthLine, cups_raster_t * ras );
119 static  void    ShareRVBtoMemWindow     ( long Height, long Width, long WidthLine, cups_raster_t * ras, int isPortrait );
120 int             Sharpen                 ( unsigned char * lpMemIn, long Width, long Height );
121
122 // --- dbg
123
124 void            ViewInfo                ( const ppd_file_t * ppd, const cups_page_header_t * header );
125 void            ViewInfoPPD             ( const ppd_file_t * ppd );
126
127 // ----------------------------------------------------
128 //  void StartPage(const ppd_file_t * ppd,  
129 //                 const cups_page_header_t * header,
130 //                 cups_raster_t * ras)
131 //
132 // @author sa
133 // ----------------------------------------------------
134 void Setup(void)
135 {
136     info("Setup()");
137 }
138
139 // ----------------------------------------------------
140 //  void StartPage(const ppd_file_t * ppd,  
141 //                 const cups_page_header_t * header,
142 //                 cups_raster_t * ras)
143 //
144 // @author sa
145 // ----------------------------------------------------
146 void StartPage(const ppd_file_t * ppd,  /* I - PPD file */
147                const cups_page_header_t * header,   /* I - Page header */
148                cups_raster_t * ras)
149 {
150     int   putB = 0;
151     int   overfb = 1;
152     int   a;
153     int   b;
154     int   iColorSmooth; 
155     int   face = RECTO;
156     
157 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
158     
159     struct sigaction action;    /* Actions for POSIX signals */
160     
161 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
162     
163 #ifdef HAVE_SIGSET      /* Use System V signals over POSIX to avoid bugs */
164     
165     sigset(SIGTERM, CancelJob);
166     
167 #elif defined(HAVE_SIGACTION)
168     
169     memset(&action, 0, sizeof(action));
170     sigemptyset(&action.sa_mask);
171     action.sa_handler = CancelJob;
172     sigaction(SIGTERM, &action, NULL);
173     
174 #else
175     signal(SIGTERM, CancelJob);
176 #endif /* HAVE_SIGSET */
177     
178     info("StartPage()");
179     
180     if      (!(strcasecmp(ColorSmooth, "Classic")))     iColorSmooth = 1;
181     else if (!(strcasecmp(ColorSmooth, "High")))        iColorSmooth = 2;
182     else if (!(strcasecmp(ColorSmooth, "VeryHigh")))    iColorSmooth = 3;
183     
184         debug("Color %d", iColorSmooth);
185         
186     if ( (header->Duplex || cSides) && ((page & 1) == 0) )
187     {       
188         face = VERSO;
189                 //info("+++AT+FH:TRAITEMENT VERSO");
190         
191         if(page & 0x01) 
192             overfb = 1; //front
193         else
194             overfb = 2; //back
195     }
196         else
197         {
198                 //info("+++AT+FH:TRAITEMENT RECTO");
199         }
200     
201     if  (   !(strcasecmp(header->MediaColor, "K"))      || !(strcasecmp(header->MediaColor, "KBL"))
202          || !(strcasecmp(header->MediaColor, "KGO"))    || !(strcasecmp(header->MediaColor, "H"))
203          || !(strcasecmp(header->MediaColor, "KGR"))    || !(strcasecmp(header->MediaColor, "KSI"))
204          || !(strcasecmp(header->MediaColor, "KSC"))    || !(strcasecmp(header->MediaColor, "KA"))
205          || !(strcasecmp(header->MediaColor, "KW"))     || !(strcasecmp(header->MediaColor, "KR")))
206     {
207         info("PRINT K");
208         ConvertRVBtoK(&lpMem[4 * (dwSizeNeeded / 5)], dwSizeNeeded, 1016, 648, &lpMem[3 * (dwSizeNeeded / 5)], face);
209         DBNC(0,1,0);
210     }
211     else if(!(strcasecmp(header->MediaColor, "KO")))
212     {
213         info("PRINT KO");
214         ConvertRVBtoK(&lpMem[4 * (dwSizeNeeded / 5)], dwSizeNeeded, 1016, 648, &lpMem[3 * (dwSizeNeeded / 5)], face);
215         DBNC(0,1,overfb);
216     }
217     else if(!(strcasecmp(header->MediaColor, "YMCKO")) || 
218             !(strcasecmp(header->MediaColor, "YMCKOS")))
219     {
220         info("PRINT YMCKO");
221         if(!(strcasecmp(header->MediaColor, "YMCKOS")))
222         {
223             if(DetectAuto)   // fhl - 01/08/08 - bug fixed 
224             {
225                 GetFirstYMCDot(1016, 648 , &a, &b);
226                 output("\033Psp;%.4d\015", b);
227                 debug("DetectAuto \033Psp;%.4d\015", b);
228             }
229             else
230             {
231                 output("\033Psp;%.4d\015", StartDist );
232                 debug("StartDist \033Psp;%.4d\015", StartDist );
233             }
234         }
235         if (toupper(BlackIn[face]) != 'N')
236             putB = 1;
237         else
238         {
239             putB = 0;
240             KinYMC(1016, 648);
241         }
242         DBNC(iColorSmooth,putB,overfb);
243     }
244     else if (!(strcasecmp(header->MediaColor, "ymckok")))
245     {
246         if (toupper(BlackIn[RECTO]) != 'N')
247             putB = 1;
248         else
249         {
250             putB = 0;
251             KinYMC(1016, 648);
252         } 
253         
254         if(header->Duplex || cSides)
255         {
256             if (page & 0x01)    
257             {
258                 info("PRINT FRONT YMCKOK");
259                 DBNC(iColorSmooth,putB,overfb);
260             }
261             else
262             {
263                 info("PRINT BACK YMCKOK");
264                 ConvertRVBtoK(&lpMem[4 * (dwSizeNeeded / 5)], dwSizeNeeded, header->cupsHeight, header->cupsWidth, &lpMem[3 * (dwSizeNeeded / 5)], VERSO);
265                 DBNC(0,1,0);
266             }
267         }
268         else 
269         {
270             info("PRINT FRONT YMCKOK");
271             DBNC(iColorSmooth,putB,overfb);
272         }
273     }
274 }
275
276 // ----------------------------------------------------
277 //  void EndPage(const cups_page_header_t * header) 
278 //
279 // @author sa
280 // ----------------------------------------------------
281 void EndPage(const cups_page_header_t * header) 
282 {
283 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
284     struct sigaction action;    /* Actions for POSIX signals */
285 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
286     
287 #ifdef HAVE_SIGSET      /* Use System V signals over POSIX to avoid bugs */
288     sigset(SIGTERM, SIG_IGN);
289 #elif defined(HAVE_SIGACTION)
290     memset(&action, 0, sizeof(action));
291     sigemptyset(&action.sa_mask);
292     action.sa_handler = SIG_IGN;
293     sigaction(SIGTERM, &action, NULL);
294 #else
295     signal(SIGTERM, SIG_IGN);
296 #endif /* HAVE_SIGSET */
297     
298     info("EndPage()");
299 }
300
301 // ----------------------------------------------------
302 //  void Shutdown(void)
303 //
304 // @author sa
305 // ----------------------------------------------------
306 void Shutdown(void)
307 {
308     info("Shutdown()");
309 }
310
311 // ----------------------------------------------------
312 //  void CancelJob(int sig)     
313 //
314 // @author sa
315 // ----------------------------------------------------
316 void CancelJob(int sig)     
317 {
318     info("CancelJob()");
319     if(lpRecto)
320     {
321         debug("CancelJob lpRecto Free memory()");
322         free(lpRecto);
323         lpRecto = NULL;
324     }
325     if(lpVerso)
326     {
327         debug("CancelJob lpVerso Free memory()");
328         free(lpVerso);
329         lpVerso = NULL;
330     }   
331 }
332
333 // ----------------------------------------------------
334 //  main()
335 //
336 // @authors sa, fhl
337 // ----------------------------------------------------
338
339 int main(int argc, char *argv[])        
340 {
341     cups_raster_t           *ras;                   /* Raster stream for printing */
342     cups_page_header_t      header;                 /* Page header from file */
343     ppd_file_t              *ppd;                   /* PPD file */
344     ppd_option_t            *option;                /* PPD option */
345     cups_option_t           *options;               /* CUPS options */
346     int                     model;                  /* Printer Model */
347     int                     fd;                     /* File descriptor */
348     int                     num_options;            /* Number of CUPS options */
349     const char              *val;                   /* CUPS option value */
350     char                    insert;                 /* insert mode */
351     int                     hopper =0;              
352     int                     feeder =0;
353     unsigned int            index_copy, NbCopy;     /* Numbers of copies */
354     char                    end_usb[65];
355     int                     i;
356     int                     appleorientation;       /* apple specific parameter */
357     int                     appleduplex;            /* apple specific parameter */
358     int                     isPortrait=0;           /* gestion du mode portrait */
359     
360     lpVerso = NULL;
361     lpRecto = NULL;
362     
363     // Make sure status messages are not buffered...
364     setbuf(stderr, NULL);
365     
366     info("Start Process");
367     
368     if (argc < 6 || argc > 7)
369     {
370         //We don't have the correct number of arguments; write an error message and return.
371         printf("rastertoevolis - version %s\n", LVERSION);
372         fatal("rastertoevolis job-id user title copies options [file]");
373         return (STATUS);
374     }
375     
376     //Open the page stream...
377     if (argc == 7) 
378     {
379         if ((fd = open(argv[6], O_RDONLY)) == -1)
380         {
381             fatal("Unable to open raster file.");
382             sleep(1);
383             return (STATUS);
384         }
385     }
386     else
387     {
388         fd = 0;
389     }
390     
391     info( "[EVO] executing rastertoevolis version %s ...", LVERSION );
392     ppd = ppdOpenFile(getenv("PPD"));
393     
394     model = EvolisModelNumberFromPPD( ppd->modelname );
395     info("%s %d",ppd->modelname,model);
396     
397     ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
398     
399     Setup();
400     
401     //---Get the STP options, if any
402     num_options = cupsParseOptions(argv[5], 0, &options);
403     
404 #ifdef MACOSX
405     
406     //------ MACOSX parameters
407     
408     appleduplex = myGetIntOption( "com.apple.print.PrintSettings.PMDuplexing..n.", num_options, options, ppd, -99 );
409     debug("appleduplex : %d", appleduplex);
410     
411     // fhl - 08/07/08 - unfification linux/Mac
412     if (appleduplex > 1) cSides = 1;
413     else cSides = 0;
414     
415     appleorientation = myGetIntOption( "com.apple.print.PrintSettings.PMOrientation..n.", num_options, options, ppd, -99 );
416     debug("appleorientation : %d", appleorientation);
417     
418         if (appleorientation>0) 
419                 isPortrait = ( appleorientation == 2 || appleorientation == 3 ); 
420     else
421                 isPortrait = ( header.Orientation == 1 || header.Orientation == 3 || cOrientation == PORTRAIT );
422 #else
423     isPortrait = ( header.Orientation == 1 || header.Orientation == 3 || cOrientation == PORTRAIT );
424 #endif // MacOS
425     
426     // --- Page Setup options
427
428     if (! GetPageSetupOption( num_options, options, ppd ))
429             info("Error: an error occured during the processing of the evolis options");
430
431     // --- Ribbon settings
432     
433     if ((val = cupsGetOption("InkType", num_options, options)) != NULL)
434         strcpy(InkType, val);
435     else
436         memset(InkType,0x00,9);
437     
438     debug("InkType : %s", InkType);
439     
440     // --- Evolis Printer Settings 
441
442     if (! GetEvolisOption(num_options,options,ppd))
443             info("Error: an error occured during the processing of the evolis options");
444                 
445     // --- MAG OPTIONS
446  
447     if (! GetMagOption( &MagInfoCard, num_options, options, ppd ) )
448             info("Error: an error occured during the parsing of the magnetic encoding options");
449     
450     // --- LAMINATION OPTIONS
451         
452     if (model == SECURION) 
453         if (! GetLaminationOption( &LamInfo, num_options, options, ppd ) )
454             info("Error: an error occured during the parsing of the lamination options");
455         
456     // --- PASSTHROUGH OPTION (PROCESSING)
457     
458     if (! ProcessPassthroughOption( num_options, options, ppd ) )
459             info("Error: an error occured during the processing of the passthrough options");
460         
461     // ---- BEGIN OF PRINTING PROCESS
462     
463     if (cupsRasterReadHeader(ras, &header))
464     {
465         ViewInfo(ppd,&header);
466         info("model : %d", model); // fhl - test - todo remove
467         
468         //Coherent info between manual add option and auto cups add option
469         if(cOrientation)    header.Orientation  = cOrientation; 
470         if(cSides != -1)    header.Duplex       = cSides; 
471         
472         /* ------------ */  
473         
474         //if(cupsRasterReadHeader(ras, &header))
475         
476         //  ViewInfo(ppd,&header);  // fhl - test - to comment
477         
478         if(model == QUANTUM) 
479         {
480             if      (!(strcasecmp(header.OutputType, "AutoH")))     hopper = 0;
481             else if (!(strcasecmp(header.OutputType, "AlterH")))    hopper = 3;
482             else if (!(strcasecmp(header.OutputType, "Tray1")))     hopper = 1;
483             else if (!(strcasecmp(header.OutputType, "Tray2")))     hopper = 2;
484             else                                                    hopper = 0;
485             
486             feeder = 5;
487             if ( !(strcasecmp(header.MediaType, "Feeder1") ))  //header.MediaWeight == 1)
488                 feeder = 1;
489             else if (!(strcasecmp(header.MediaType, "Feeder2"))) //(header.MediaWeight == 2)
490                 feeder = 2;
491             else if (!(strcasecmp(header.MediaType, "Alter")))  //(header.MediaWeight == 3)
492                 feeder = 3;
493             else if (!(strcasecmp(header.MediaType, "Auto")))  //(header.MediaWeight == 0)
494                 feeder = 0;
495             
496             if (feeder != 5)
497             {
498                 info("Set Feeder and output hopper");
499                 output("\033Piem;%d;%d\015", feeder,hopper);
500                 //info("\033Piem;%d;%d\015", feeder,hopper);
501             }
502         }
503         
504         if (model == TATTOO) 
505         {
506             insert = '0';
507             if (!(strcasecmp(header.MediaType, "Feeder"))) //header.MediaWeight == 1)
508                 insert = 'F';
509             else if (!(strcasecmp(header.MediaType, "Manual"))) //header.MediaWeight == 2)
510                 insert = 'M';
511             else if (!(strcasecmp(header.MediaType, "Auto"))) //header.MediaWeight == 3)
512                 insert = 'B';
513             //else insert = '0';
514             
515             if (insert != '0')
516             {
517                 info("Set Feeder");
518                 output("\033Pmi;%c\015", insert);
519             }
520         }
521         
522         // Process Card Test as needed...
523         
524         if ( !(strcasecmp(EjectCard, "NONE")) ) // || !(strcasecmp(EjectCard, "Keep"))) {
525         {
526             if (header.cupsColorSpace == CUPS_CSPACE_RGB || CUPS_CSPACE_CMYK )
527                 colorspace = CUPS_CSPACE_RGB;
528             else
529             {
530                 fatal("Fail CUPS_CSPACE_RGB ");
531                 goto quitmain;
532             }
533             
534             //  dwSizeNeeded: Size of lpRecto in pixels
535             if (header.cupsBitsPerPixel == 24)
536             {
537                 //dwSizeNeeded = header.cupsHeight * header.cupsWidth * 5;
538                 dwSizeNeeded = 1016 * 648 *  5;
539                 if(lpRecto)
540                 {
541                     debug("lpRecto Free memory");
542                     free(lpRecto);
543                     lpRecto = NULL;
544                 }
545                 lpRecto = malloc(dwSizeNeeded);
546                 if (lpRecto)
547                     debug("lpRecto: size demands %d pixels... ", dwSizeNeeded);
548                 else
549                 {
550                     fatal("Fail memory for lpRecto : %d pixels... ", dwSizeNeeded);
551                     goto quitmain;
552                 } //End of lpRecto
553                 
554                 if(header.Duplex || cSides)
555                 {
556                     //dwSizeNeeded = header.cupsHeight * header.cupsWidth * 5;
557                     dwSizeNeeded = 1016 * 648 *  5;
558                     if(lpVerso)
559                     {
560                         debug("lpVerso Free memory");
561                         free(lpVerso);
562                         lpVerso = NULL;
563                     }
564                     lpVerso = malloc(dwSizeNeeded);
565                     if (lpVerso)
566                         debug("lpVerso: size demands %d pixels... ", dwSizeNeeded);
567                     else
568                     {
569                         fatal("Fail memory for lpVerso : %d pixels ", dwSizeNeeded);
570                         goto quitmain;
571                     }
572                 }// end of if Duplex
573             }//end of cupRaster = 24
574             else
575             {
576                 info("header->cupsBitsPerPixel... : %d ", header.cupsBitsPerPixel);
577                 fatal("Fail Not mode 24 bits ");
578                 goto quitmain;
579             }//End of lpRecto
580             
581             // Process pages as needed...
582             
583             // ====== BEGIN OF THE PRINTING PROCESS
584             
585             NbCopy = header.NumCopies;
586             page = 0;
587             do 
588             {
589                 for ( NbCopy = header.NumCopies ; NbCopy > 0 ; NbCopy-- )
590                 {
591                     page++;
592                     if (model==SECURION) 
593                     {
594                         output("\033PLds;0;%c;%d;%d;%c;%s\015", LamInfo.lamType, LamInfo.lamSpeed, LamInfo.lamTemp, LamInfo.lamAlt, LamInfo.lamDesc);
595                         output("\033PLr;0\015\033PLm;%c;%c\015", LamInfo.defLam, LamInfo.exitLam);
596                     }
597                     
598                     //color panel
599                                         
600                     info("PAGE: %d %d", page, header.NumCopies);
601                     
602                     if ( (header.Duplex || cSides) && ((page & 1) == 0) ) // even page number and two-sided printing
603                     {
604                         info("SEQUENCE VERSO");
605                         output("\033Sv\015");
606                         if (model != TATTOO) 
607                         {
608                             info("Set color ribbon/panels temperature");
609                             output("\033Pl;a;=;%d\015", Brightness[VERSO]);
610                             output("\033Pc;a;=;%d\015", Contrast[VERSO]);
611                             output("\033Pc;o;=;%d\015", SensibilityO[VERSO]);
612                         }
613                         info("Set black ribbon/panel temperature");
614                         output("\033Pc;k;=;%d\015", SensibilityK[VERSO]);
615                         // To improve output("\033Pr;%s\015",header.MediaColor);
616                         SetOverlayRegion(overlayRegion[VERSO]);
617                         lpMem = lpVerso;
618                     }
619                     else 
620                     {
621                         info("SEQUENCE RECTO");
622                         output("\033Ss\015\033Sr\015");
623                         if (model != TATTOO) 
624                         {
625                             info("Set color ribbon/panels temperature");
626                             output("\033Pl;a;=;%d\015", Brightness[RECTO]);
627                             output("\033Pc;a;=;%d\015", Contrast[RECTO]);
628                             output("\033Pc;o;=;%d\015", SensibilityO[RECTO]);
629                         }
630                         info("Set black ribbon/panel temperature");
631                         output("\033Pc;k;=;%d\015", SensibilityK[RECTO]);
632                         output("\033Ps;k;=;%d\015", QualityK); // meme pour Recto/Verso
633                         output("\033Pr;%s\015",header.MediaColor);
634                         SetOverlayRegion(overlayRegion[RECTO]);
635                         
636                         for (i=0;i<3;i++)
637                             if( MagInfoCard.Track[i].data[0] ) 
638                             {
639                                 info("Download track %d", i+1);
640                                 output( "%s", MagInfoCard.Track[i].data );
641                             }
642                         lpMem = lpRecto;
643                     }
644                     
645                     if ((header.cupsHeight * header.cupsWidth) == 658368 )
646                         ShareRVBtoMem(header.cupsHeight, header.cupsWidth,  header.cupsBytesPerLine, ras);
647                     else
648                         ShareRVBtoMemWindow(header.cupsHeight, header.cupsWidth,  header.cupsBytesPerLine, ras, isPortrait);
649                     
650                     if (!(strcasecmp(Soften, "FALSE")))
651                     {
652                         Sharpen( &lpMem[0],648,1016);
653                         Sharpen( &lpMem[1016*648],648,1016);
654                         Sharpen( &lpMem[2*1016*648],648,1016);
655                     }
656                     
657                     StartPage(ppd, &header, ras);
658                     EndPage(&header);
659                     
660                     if (  (!(header.Duplex || cSides )) || ((page & 1) == 0) ) // even page number or not two-sided printing)
661                                         {
662                                                 info("Eject card");
663                                                 output("\033Se\015");
664                                         }
665                 }    // for NbCopy  
666                                 info("--- next cupsRasterReadHeader please");
667             }
668             while (cupsRasterReadHeader(ras, &header));
669                         
670                         if ( (header.Duplex || cSides ) && (page & 1) ) // odd page number and two-sided printing
671                         {
672                                 info("Eject card");
673                                 output("\033Se\015");
674                         }
675                         
676             memset(end_usb,0x00,64);
677             if(fwrite( end_usb,sizeof(unsigned char),64,stdout) != 64) 
678             {
679                 debug("Error: fails print end usb ...\n");
680             }
681             
682         }//End test Card
683         else
684         {
685             page = 1;
686             do 
687             {
688                 //cupsRasterReadPixels(ras, lpImgBuf, WidthLine)
689             }
690             while (cupsRasterReadHeader(ras, &header));
691         
692 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
693             struct sigaction action;    
694 #endif 
695 #ifdef HAVE_SIGSET
696             sigset(SIGTERM, CancelJob);
697 #elif defined(HAVE_SIGACTION)
698             memset(&action, 0, sizeof(action));
699             
700             sigemptyset(&action.sa_mask);
701             action.sa_handler = CancelJob;
702             sigaction(SIGTERM, &action, NULL);
703 #else
704             signal(SIGTERM, CancelJob);
705 #endif
706             info("StartPage()");
707             
708             if (! ProcessSpecialCommands( EjectCard, &MagInfoCard ) )
709                 info("Error: an error occured during specific command processing");
710             
711             memset(end_usb,0x00,64);
712             if(fwrite( end_usb,sizeof(unsigned char),64,stdout) != 64) 
713                 debug("Error: fails print end usb ...\n");
714             EndPage(&header);
715         }
716         
717     quitmain:;
718         
719         //Free memory...
720         if(lpRecto)
721         {
722             debug("lpRecto Free memory");
723             free(lpRecto);
724             lpRecto = NULL;
725         }
726         if(lpVerso)
727         {
728             debug("lpVerso Free memory");
729             free(lpVerso);
730             lpVerso = NULL;
731         }
732         Shutdown();
733         ppdClose(ppd);
734         // Close the raster stream...
735         cupsRasterClose(ras);
736         if (fd != 0)
737             close(fd);
738         // If no pages were printed, send an error message...
739         if (page == 0)
740             fatal("ERROR: No pages found!\n");
741         if (!STATUS) 
742         {
743             info("Job is done : successful operation(s)");
744         } 
745         else 
746         {
747             info("Error processing Job");
748         }
749         info("End of printing - Returning %d", STATUS);
750         return (STATUS);
751     }
752 }
753
754 // ----------------------------------------------------
755 //  static void ShareRVBtoMemWindow(long Height, long Width, long WidthLine, cups_raster_t * ras, int isPortrait )
756 //
757 // @author sa
758 // ----------------------------------------------------
759 // pMem ppV
760 //                       ___________
761 //                      |           |
762 //                      |           |
763 //                      |   Yellow  |
764 //                      |           |
765 //                      |___________|
766 //                      |           |
767 //                      |           |
768 //                      |   Magenta |
769 //                      |           |
770 //                      |___________|
771 //                      |           |
772 //                      |           |
773 //                      |   Cyan    |
774 //                      |           |
775 //                      |___________|
776 //                      |           |
777 //                      |           |
778 //                      |   Black   |
779 //                      |           |
780 //                      |___________|
781 //                      |           |
782 //                      |           |
783 //                      |   Grey    |
784 //                      |           |
785 //                      |___________|
786 // ----------------------------------------------------
787 static void ShareRVBtoMem(long Height, long Width, long WidthLine, cups_raster_t * ras)
788 {
789     //Pointeur sur image buffer
790     unsigned char *lpImgBuf, *lpYellow, *lpMagenta, *lpCyan, *lpBlack, *lpGray;
791     //valeur RVB courante & pr
792     unsigned char red, green, blue, r, g, b;
793     //index pour scruter le fichier bitmap
794     long index_line, index_dot;
795     long  stpt = 0;
796     long  offx = 0, offy = 0;
797     
798     lpImgBuf = malloc(WidthLine);
799     if (!lpImgBuf) 
800     {
801         fatal("ShareRVBtoMem fail to book memory: size requested %d bytes... \n", WidthLine);
802         return;
803     }
804     lpYellow = &lpMem[0];
805     //memset(lpYellow,0x00,Width * Height);
806     memset(lpYellow,0x00,1016*648);
807     lpMagenta = &lpMem[Width * Height];
808     //memset(lpMagenta,0x00,Width * Height);
809     memset(lpMagenta,0x00,1016*648);
810     lpCyan = &lpMem[2 * Width * Height];
811     //memset(lpCyan,0x00,Width * Height);
812     memset(lpCyan,0x00,1016*648);  
813     lpBlack = &lpMem[3 * Width * Height];
814     //memset(lpBlack,0x00,Width * Height);
815     memset(lpBlack,0x00,1016*648);
816     lpGray = &lpMem[4 * Width * Height];
817     //memset(lpGray,0xFF,Width * Height);
818     memset(lpGray,0xFF,1016*648);
819     
820     ////////////////
821     //CAS PORTRAIT//
822     ////////////////
823     if (Height >= Width) 
824     {
825         info("Portrait");
826         //Pour toutes les lignes de l'image
827         for (index_line = 0; index_line < Height; index_line++) 
828         {
829             if (cupsRasterReadPixels(ras, lpImgBuf, WidthLine) == WidthLine) 
830             {
831                 r = 0xFF;
832                 g = 0xFF;
833                 b = 0xFF;
834                 stpt = 0;
835                 //Pour tous les points de la ligne
836                 for (index_dot = Width; index_dot > 0; index_dot--) 
837                 {
838                     red = lpImgBuf[(index_dot * 3)];
839                     green = lpImgBuf[(index_dot * 3) + 1];
840                     blue = lpImgBuf[(index_dot * 3) + 2];
841                     lpGray[(index_line * 648) + index_dot] = (unsigned char) RgbToGray(red, green, blue);
842                     if (blue == 0x00 && green == 0x00 && red == 0x00) 
843                     {
844                         if (stpt == 0)  
845                         {
846                             //Erreur sur le premier point blanc par defaut
847                             lpYellow[(index_line * 648) + index_dot] = 0x00;
848                             lpMagenta[(index_line * 648) + index_dot] = 0x00;
849                             lpCyan[(index_line * 648) + index_dot] = 0x00;
850                             lpBlack[(index_line * 648) + index_dot] = 0xFF;
851                             //premier point trait...
852                             stpt = 1;
853                         }
854                         else 
855                         {
856                             //Cas point noir on met la couleur du point precedent
857                             lpYellow[(index_line * 648) + index_dot] = ((0xFF - b));
858                             lpMagenta[(index_line * 648) + index_dot] = ((0xFF - g));
859                             lpCyan[(index_line * 648) + index_dot] = ((0xFF - r));
860                             lpBlack[(index_line * 648) + index_dot] = 0xFF;
861                         }
862                     }
863                     else 
864                     {
865                         //Sauvegarde de la valeur precedente
866                         r = red;
867                         g = green;
868                         b = blue;
869                         //Traitement particulier pour le premier point
870                         lpYellow[(index_line * 648) + index_dot] = ((0xFF - b));
871                         lpMagenta[(index_line * 648) + index_dot] = ((0xFF - g));
872                         lpCyan[(index_line * 648) + index_dot] = ((0xFF - r));
873                         lpBlack[(index_line * 648) + index_dot] = 0x00;
874                         //premier point traite
875                         stpt = 1;
876                     }
877                 }   // for point de la line
878             }   // test read line = cupsRasterReadPixels
879         }   //for ligne
880     }   //end if H>W
881     /////////////////
882     //CAS LANDSCAPE//
883     /////////////////
884     else 
885     {
886         info("Landscape");
887         for (index_line = (Height); index_line > 0; index_line--)
888         {
889             r = 0xFF;
890             g = 0xFF;
891             b = 0xFF;
892             stpt = 0;
893             if (cupsRasterReadPixels(ras, lpImgBuf, WidthLine) == WidthLine) 
894             {
895                 for (index_dot = 0; index_dot < Width; index_dot++) 
896                 {
897                     red = lpImgBuf[(index_dot * 3)];
898                     green = lpImgBuf[(index_dot * 3) + 1];
899                     blue = lpImgBuf[(index_dot * 3) + 2];
900                     lpGray[(index_line) + (index_dot * Height)] = (unsigned char) RgbToGray(red, green, blue);
901                     if(blue == 0x00 && green == 0x00 && red == 0x00) 
902                     {
903                         if (stpt == 0)
904                         {
905                             //Erreur sur le premier point blanc par defaut
906                             lpYellow[(index_line) + (index_dot * Height)] = 0x00;
907                             lpMagenta[(index_line) + (index_dot * Height)] = 0x00;
908                             lpCyan[(index_line) + (index_dot * Height)] = 0x00;
909                             lpBlack[(index_line) + (index_dot * Height)] = 0xFF;
910                             //premier point traite
911                             stpt = 1;
912                         }
913                         else 
914                         {
915                             //Cas point noir on met la couleur du point precedent
916                             lpYellow[(index_line) + (index_dot * Height)] = ((0xFF - b));
917                             lpMagenta[(index_line) + (index_dot * Height)] = ((0xFF - g));
918                             lpCyan[(index_line) + (index_dot * Height)] = ((0xFF - r));
919                             lpBlack[(index_line) + (index_dot * Height)] = (0xFF);
920                         }
921                     }
922                     else 
923                     {
924                         //Sauvegarde de la valeur precedente
925                         r = red;
926                         g = green;
927                         b = blue;
928                         //Traitement particulier pour le premier point
929                         lpYellow[(index_line) + (index_dot * Height)] = ((0xFF - b));
930                         lpMagenta[(index_line) + (index_dot * Height)] = ((0xFF - g));
931                         lpCyan[(index_line) + (index_dot * Height)] = ((0xFF - r));
932                         lpBlack[(index_line) + (index_dot * Height)] = 0x00;
933                         //premier point traite
934                         stpt = 1;
935                     }
936                 }   // for point de la line
937             }   // test read line
938         }       //for ligne
939     }           //end else if H>W
940     free(lpImgBuf);
941
942
943 // ----------------------------------------------------
944 //  static void ShareRVBtoMemWindow(long Height, long Width, long WidthLine, cups_raster_t * ras, int isPortrait )
945 //
946 // @author sa
947 // ----------------------------------------------------
948
949 static void ShareRVBtoMemWindow(long Height, long Width, long WidthLine, cups_raster_t * ras, int isPortrait )
950 {
951     unsigned char *lpImgBuf, *lpYellow, *lpMagenta, *lpCyan, *lpBlack, *lpGray;         // Pointeur sur image buffer
952     unsigned char red, green, blue, r, g, b;                                            // valeur RVB courante & presente
953     long index_line, index_dot;                                                         // index pour scruter le fichier bitmap
954     long  stpt = 0;                                                                     // Booleen indiquant le premier bit de la chaine
955     long  offx = 0, offy = 0;
956     long  Hfix = 1016, Wfix = 648;
957     long  dot = 0, line =0;
958     
959     lpImgBuf = malloc(WidthLine);
960     if (!lpImgBuf) {
961         fatal("ShareRVBtoMem fail to book memory: size requested %d bytes... \n", WidthLine);
962         return;
963     }
964     
965     lpYellow = &lpMem[0];
966     memset(lpYellow,0x00,1016*648);
967     lpMagenta = &lpMem[1016*648];
968     memset(lpMagenta,0x00,1016*648);
969     lpCyan = &lpMem[2 * 1016*648];
970     memset(lpCyan,0x00,1016*648);
971     lpBlack = &lpMem[3 * 1016*648];
972     memset(lpBlack,0x00,1016*648);
973     lpGray = &lpMem[4 * 1016*648];
974     memset(lpGray,0xFF,1016*648);
975     
976     if ( isPortrait ) 
977     {
978         if(Width%2) 
979         {
980             cupsRasterReadPixels(ras, lpImgBuf, WidthLine);
981             //info("Read odd line ");
982             Width--;
983         }
984         if(Width > 648)
985             offx = (Width - 648)/2;
986         else
987             offx = 0;
988         
989         if(Height > 1016)
990             offy = (Height - 1016)/2;
991         else
992             offy = 0;
993         
994         Hfix = 1016;
995         Wfix = 648;
996     }
997     else 
998     {
999         if (Height%2) 
1000         {
1001             cupsRasterReadPixels(ras, lpImgBuf, WidthLine);
1002             //info("Read odd line ");
1003             Height--;
1004         }
1005         if(Width > 1016)
1006             offx = (Width - 1016)/2;
1007         else
1008             offx = 0;
1009         
1010         if(Height > 648)
1011             offy = (Height - 648)/2;
1012         else
1013             offy = 0; 
1014         Hfix = 648;
1015         Wfix = 1016;
1016     }
1017     
1018     //info(" offx : %d offy : %d", offx, offy);
1019     ////////////////
1020     //CAS PORTRAIT//
1021     ////////////////
1022     //if (Height >= Width)
1023     if ( isPortrait )
1024     {
1025         info("Portrait");
1026         for (index_line = (Height); index_line > (Height - offy); index_line--) 
1027         {
1028             cupsRasterReadPixels(ras, lpImgBuf, WidthLine);
1029         }
1030         //info(" H : %d  W: %d",Hfix,Wfix);
1031         //Pour toutes les lignes de l'image
1032         line = 0;
1033         for (index_line; index_line > offy; index_line--) 
1034         {
1035             if (cupsRasterReadPixels(ras, lpImgBuf, WidthLine) == WidthLine) 
1036             {
1037                 r = 0xFF;
1038                 g = 0xFF;
1039                 b = 0xFF;
1040                 stpt = 0;
1041                 //Pour tous les points de la ligne
1042                 dot = 648;
1043                 for (index_dot = (Width-offx); index_dot > offx; index_dot--) 
1044                 {
1045                     red = lpImgBuf[(index_dot * 3)];
1046                     green = lpImgBuf[(index_dot * 3) + 1];
1047                     blue = lpImgBuf[(index_dot * 3) + 2];
1048                     lpGray[(line*648) + (dot) ] = (unsigned char) RgbToGray(red, green, blue);
1049                     if (blue == 0x00 && green == 0x00 && red == 0x00) 
1050                     {
1051                         if (stpt == 0)  
1052                         {
1053                             //Erreur sur le premier point blanc par defaut
1054                             lpYellow[(line*648) + (dot)] = 0x00;
1055                             lpMagenta[(line*648) + (dot)] = 0x00;
1056                             lpCyan[(line*648) + (dot)] = 0x00;
1057                             lpBlack[(line*648) + (dot)] = 0xFF;
1058                             //premier point traite
1059                             stpt = 1;
1060                         }
1061                         else 
1062                         {
1063                             //Cas point noir on met la couleur du point precedent
1064                             lpYellow[(line*648) + (dot)] = ((0xFF - b));
1065                             lpMagenta[(line*648) + (dot)] = ((0xFF - g));
1066                             lpCyan[(line*648) + (dot)] = ((0xFF - r));
1067                             lpBlack[(line*648) + (dot)] = 0xFF;
1068                         }
1069                     }
1070                     else 
1071                     {
1072                         //Sauvegarde de la valeur precedente
1073                         r = red;
1074                         g = green;
1075                         b = blue;
1076                         //Traitement particulier pour le premier point
1077                         lpYellow[(line*648) + (dot)] = ((0xFF - b));
1078                         lpMagenta[(line*648) + (dot)] = ((0xFF - g));
1079                         lpCyan[(line*648) + (dot)] = ((0xFF - r));
1080                         lpBlack[(line*648) + (dot)] = 0x00;
1081                         //premier point traite
1082                         stpt = 1;
1083                     }
1084                     dot--;
1085                 }   // for point de la line
1086             }   // test read line = cupsRasterReadPixels
1087             line++;
1088         }       //for ligne
1089         for (index_line ; index_line > 0; index_line--) 
1090         {
1091             if(cupsRasterReadPixels(ras, lpImgBuf, WidthLine) != WidthLine) 
1092             {
1093                 debug("Erreur de lecture line CUPS15");
1094             }
1095         }
1096     }       //end if H>W
1097     /////////////////
1098     //CAS LANDSCAPE//
1099     /////////////////
1100     else 
1101     {
1102         info("Landscape");
1103         //info("index_line: %d",Height);
1104         for (index_line = (Height); index_line > (Height - offy); index_line--) 
1105         {
1106             if(cupsRasterReadPixels(ras, lpImgBuf, WidthLine) != WidthLine) 
1107             {
1108                 debug("erreur ");
1109             }
1110         }
1111         line = 648;//Hfix;
1112         for (index_line ; index_line > offy; index_line--) 
1113         {
1114             r = 0xFF;
1115             g = 0xFF;
1116             b = 0xFF;
1117             stpt = 0;
1118             if (cupsRasterReadPixels(ras, lpImgBuf, WidthLine) == WidthLine) 
1119             {
1120                 dot = 0;
1121                 for (index_dot = offx; index_dot < (Width - offx); index_dot++) 
1122                 {
1123                     red = lpImgBuf[(index_dot * 3)];
1124                     green = lpImgBuf[(index_dot * 3) + 1];
1125                     blue = lpImgBuf[(index_dot * 3) + 2];
1126                     lpGray[(line) + (dot * 648)] = (unsigned char) RgbToGray(red, green, blue);
1127                     if(blue == 0x00 && green == 0x00 && red == 0x00) 
1128                     {
1129                         if (stpt == 0) 
1130                         {
1131                             //Erreur sur le premier point blanc par defaut
1132                             lpYellow[(line) + (dot * 648)] = 0x00;
1133                             lpMagenta[(line) + (dot * 648)] = 0x00;
1134                             lpCyan[(line) + (dot * 648)] = 0x00;
1135                             lpBlack[(line) + (dot * 648)] = 0xFF;
1136                             //premier point traite
1137                             stpt = 1;
1138                         }
1139                         else 
1140                         {
1141                             //Cas point noir on met la couleur du point precedent
1142                             lpYellow[(line) + (dot * 648)] = ((0xFF - b));
1143                             lpMagenta[(line) + (dot * 648)] = ((0xFF - g));
1144                             lpCyan[(line) + (dot * 648)] = ((0xFF - r));
1145                             lpBlack[(line) + (dot * 648)] = (0xFF);
1146                         }
1147                     }
1148                     else 
1149                     {
1150                         //Sauvegarde de la valeur precedente
1151                         r = red;
1152                         g = green;
1153                         b = blue;
1154                         //Traitement particulier pour le premier point
1155                         lpYellow[(line) + (dot * 648)] = ((0xFF - b));
1156                         lpMagenta[(line) + (dot * 648)] = ((0xFF - g));
1157                         lpCyan[(line) + (dot * 648)] = ((0xFF - r));
1158                         lpBlack[(line) + (dot * 648)] = 0x00;
1159                         //premier point traite
1160                         stpt = 1;
1161                     }
1162                     dot++;
1163                 }   // for point de la line
1164             }   // test read line
1165             line--;
1166         }       //for ligne
1167         for (index_line; index_line > 0; index_line--) 
1168         {
1169             if(cupsRasterReadPixels(ras, lpImgBuf, WidthLine) != WidthLine) 
1170             {
1171                 debug("erreur ");
1172             }
1173         }
1174     }           //end else if H>W
1175     free(lpImgBuf);
1176 }
1177
1178
1179
1180 //Sharpen (medium)
1181 int SharpenPattern2[5][5] = {
1182     {-1,-1,-1,-1,-1},
1183     {-1,-1,-1,-1,-1},
1184     {-1,-1,49,-1,-1},
1185     {-1,-1,-1,-1,-1},
1186     {-1,-1,-1,-1,-1}
1187 };
1188
1189 // ----------------------------------------------------
1190 //  int Sharpen(unsigned char * lpMemIn, long Width, long Height)
1191 //
1192 // @author sa
1193 // ----------------------------------------------------
1194
1195 int Sharpen(unsigned char * lpMemIn, long Width, long Height)
1196 {
1197     long    index_line = 0,index_dot = 0;
1198     unsigned char *lpbDataOut , *lpbData;
1199     
1200     int  final = 0;
1201     int x= 0,y=0;
1202     int divisionFactor = 0;
1203     
1204     lpbDataOut = NULL;
1205     lpbDataOut = malloc(Width * Height);
1206     if (lpbDataOut)
1207         debug("lpDataOut: size demands %d pixels... ", Width * Height);
1208     else
1209         fatal("Fail memory for lpDataOut : %d pixels ", Width * Height);
1210     
1211     for(y=-2; y<=2; y++)     // and for each pixel around our
1212         for(x=-2; x<=2; x++)   //  "hot pixel"...
1213             divisionFactor += SharpenPattern2[x+2][y+2];
1214     
1215     //lpbData ppV mem bmp brute
1216     lpbData = &lpMemIn[0];
1217     //lpbDataOut = &lpMemOut[0];
1218     for(index_line = 2; index_line < Height -2; index_line++)
1219         for(index_dot = 2 ; index_dot < Width -2; index_dot++)
1220         {
1221             //gridCounter=0;      // reset some values
1222             final = 0;
1223             for(y=-2; y<=2; y++)     // and for each pixel around our
1224                 for(x=-2; x<=2; x++)   //  "hot pixel"...
1225                     final += lpbData[(index_dot + x) + ((index_line + y) * Width)] * SharpenPattern2[y+2][x+2];
1226             
1227             // and put it back into the right range
1228             final /= divisionFactor;
1229             //iMemFilter[index_dot + (index_line * Width)] = final;
1230             lpbDataOut[(index_dot) + ((index_line) * Width)] = final;
1231             if(final > 255)
1232                 lpbDataOut[(index_dot) + ((index_line) * Width)] = 0xFF;
1233             else if(final < 0)
1234                 lpbDataOut[(index_dot) + ((index_line) * Width)] = 0x00;
1235         }
1236     index_dot = Height * Width;
1237     for(index_line = 0; index_line < index_dot; index_line++)
1238         lpbData[index_line] =  lpbDataOut[index_line];
1239     
1240     //Free memory...
1241     if(lpbDataOut)
1242     {
1243         debug("lpbDataOut Free memory");
1244         free(lpbDataOut);
1245         lpbDataOut = NULL;
1246     } 
1247     
1248     
1249     return(1);
1250 }
1251
1252 // ----------------------------------------------------
1253 //  void ViewInfo(const ppd_file_t * ppd, const cups_page_header_t * header)
1254 //
1255 // @brief debug
1256 // @author sa
1257 // @param dest :  ppd param pointer and cups header info
1258 // ----------------------------------------------------
1259 void ViewInfo(const ppd_file_t * ppd, const cups_page_header_t * header)
1260 {
1261     
1262     info("-----------------------------------");
1263     info("header->cupsWidth... : %d ", header->cupsWidth);
1264     
1265     info("header->cupsHeight... : %d ", header->cupsHeight);
1266     
1267     info("header->MediaClass... : %s ", header->MediaClass);
1268     info("header->MediaColor... : %s ", header->MediaColor);
1269     info("header->MediaType... : %s ", header->MediaType);  
1270     info("header->OutputType... : %s ", header->OutputType);
1271     info("header->CutMedia... : %d ", header->CutMedia);
1272     
1273     info("header->AdvanceDistance... : %s ", header->AdvanceDistance);
1274     info("header->AdvanceMedia... : %d ", header->AdvanceMedia);    // Width of page image in pixels //
1275     info("header->Collate... : %d ", header->Collate);  // Width of page image in pixels //
1276     
1277     info("header->Duplex... : %d ", header->Duplex);    
1278     info("header->HWResolution... : %d %d ", header->HWResolution[0],header->HWResolution[1]);
1279     info("header->ImagingBoundingBox... : %d %d %d %d", header->ImagingBoundingBox[0],header->ImagingBoundingBox[1],header->ImagingBoundingBox[2],header->ImagingBoundingBox[3]);   
1280     info("header->InsertSheet... : %d ", header->InsertSheet);  // Width of page image in pixels //
1281     info("header->Jog... : %d ", header->Jog);  // Width of page image in pixels //
1282     info("header->LeadingEdge... : %d ", header->LeadingEdge);  // Width of page image in pixels //
1283     info("header->Margins... : %d , %d", header->Margins[0],header->Margins[1]);    
1284     info("header->ManualFeed... : %d ", header->ManualFeed);
1285     info("header->MediaPosition... : %d ", header->MediaPosition);  
1286     info("header->MediaWeight... : %d ", header->MediaWeight);
1287     info("header->MirrorPrint... : %d ", header->MirrorPrint);  // Width of page image in pixels //
1288     info("header->NegativePrint... : %d ", header->NegativePrint);  // Width of page image in pixels //
1289     info("header->NumCopies... : %d ", header->NumCopies);  
1290     info("header->Orientation... : %d ", header->Orientation);
1291     info("header->OutputFaceUp... : %d ", header->OutputFaceUp);    // Width of page image in pixels //
1292     info("header->PageSize... : %d ,%d ", header->PageSize[0], header->PageSize[1]);
1293     info("header->Separations... : %d ", header->Separations);  // Width of page image in pixels //
1294     info("header->TraySwitch... : %d ", header->TraySwitch);
1295     info("header->Tumble... : %d ", header->Tumble);    
1296     info("header->cupsWidth... : %d ", header->cupsWidth);
1297     info("header->cupsHeight... : %d ", header->cupsHeight);
1298     info("header->MediaType... : %d ", header->cupsMediaType);
1299     info("header->cupsBitsPercolor... : %d ", header->cupsBitsPerColor);    
1300     info("header->cupsBitsPerPixel... : %d ", header->cupsBitsPerPixel);    
1301     info("header->cupsBitsPerline... : %d ", header->cupsBytesPerLine); 
1302     info("header->cupsColorOrder... : %d ", header->cupsColorOrder);    
1303     info("header->cupsColorSpace... : %d ", header->cupsColorSpace);    
1304     info("header->cupsCompression... : %d ", header->cupsCompression);  
1305     info("header->cupsRowCount... : %d ", header->cupsRowCount);    
1306     info("header->cupsRowFeed... : %d ", header->cupsRowFeed);  
1307     info("header->cupsRowStep... : %d ", header->cupsRowStep);  
1308     info("header->cupsColorSpace... : %d ", header->cupsColorSpace);    
1309     info("header->cupsColorOrder... : %d ", header->cupsColorOrder);    
1310     info("header->InsertSheet... : %d ", header->InsertSheet);  // Width of page image in pixels //
1311     info("header->Jog... : %d ", header->Jog);  // Width of page image in pixels //
1312     info("header->LeadingEdge... : %d ", header->LeadingEdge);  // Width of page image in pixels //
1313     info("header->ManualFeed... : %d ", header->ManualFeed);    // Width of page image in pixels //
1314     info("header->MediaPosition... : %d ", header->MediaPosition);  // Width of page image in pixels //
1315     info("header->MediaWeight... : %d ", header->MediaWeight);  // Width of page image in pixels //
1316     info("header->MirrorPrint... : %d ", header->MirrorPrint);  // Width of page image in pixels //
1317     info("header->NegativePrint... : %d ", header->NegativePrint);  // Width of page image in pixels //
1318     info("header->OutputFaceUp... : %d ", header->OutputFaceUp);    // Width of page image in pixels //
1319     info("header->Separations... : %d ", header->Separations);  // Width of page image in pixels //
1320     info("-----------------------------------");
1321 }
1322
1323 // ----------------------------------------------------
1324 //  void ViewInfoPPD(const ppd_file_t * ppd)
1325 //
1326 // @brief debug
1327 // @author sa
1328 // @param dest :  ppd param pointer
1329 // ----------------------------------------------------
1330 void ViewInfoPPD(const ppd_file_t * ppd)
1331 {
1332     info("PPD->Langage Level # - %d", ppd->language_level);
1333     
1334     
1335     info("PPD->color_device # - %d", ppd->color_device);
1336     info("PPD->variable_sizes # - %d", ppd->variable_sizes);
1337     info("PPD->accurate_screens # - %d", ppd->accurate_screens);
1338     info("PPD->contone_only # - %d", ppd->contone_only);
1339     info("PPD->landscape # - %d", ppd->landscape);
1340     info("PPD->model_number # - %d", ppd->model_number);
1341     info("PPD->manual_copies # - %d", ppd->manual_copies);
1342     info("PPD->throughput # - %d", ppd->throughput);
1343     info("PPD->colorspace # - %d", ppd->colorspace);
1344     info("PPD->num_emulations # - %d", ppd->num_emulations);
1345     info("PPD->emulation # - %s", ppd->emulations);
1346     
1347     info("PPD->jcl_begin # - %s", ppd->jcl_begin);
1348     info("PPD->pjcl_end # - %s", ppd->jcl_end);
1349     info("PPD->lang_encoding # - %s", ppd->lang_encoding);
1350     
1351     info("PPD->lang_version # - %s", ppd->lang_version);
1352     info("PPD->modelname # - %s", ppd->modelname);
1353     info("PPD->ttrasterizer # - %s", ppd->ttrasterizer);
1354     info("PPD->manufacturer # - %s", ppd->manufacturer);
1355     info("PPD->product # - %s", ppd->product);
1356     info("PPD->nickname # - %s", ppd->nickname);
1357     info("PPD->shortnickname # - %s", ppd->shortnickname);
1358     info("PPD->num_groups # - %d", ppd->num_groups);
1359     info("PPD->num_sizes # - %d", ppd->num_sizes);
1360     info("PPD->sizes[0] # - %d, %s, %f, %f, %f, %f, %f, %f", ppd->sizes[0].marked,ppd->sizes[0].name,
1361          ppd->sizes[0].width,ppd->sizes[0].length,ppd->sizes[0].left,ppd->sizes[0].right,ppd->sizes[0].top );
1362     
1363     
1364     info("PPD->custom_min # - %f, %f", ppd->custom_min[0],ppd->custom_min[1]);
1365     info("PPD->custom_max # - %f, %f", ppd->custom_max[0],ppd->custom_max[1]);
1366     info("PPD->custom_margins # - %f,%f,%f,%f", ppd->custom_margins[0],ppd->custom_margins[1]);
1367     info("PPD->num_consts # - %d", ppd->num_consts);
1368     
1369     info("PPD->num_fonts # - %d", ppd->num_fonts);
1370     info("PPD->num_profiles # - %d", ppd->num_profiles);
1371     info("PPD->num_filters # - %d", ppd->num_filters);
1372     info("PPD->filters # - %s", ppd->filters[0]);
1373     
1374     info("PPD->flip_duplex # - %d", ppd->flip_duplex);
1375 }
1376
1377 // ----------------------------------------------------
1378 //  int myGetIntOption( char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, int defaultValue )
1379 //
1380 // @brief get an option (int) from cups then ppd option then default
1381 // @author fhl
1382 // @param dest :  the name of the option, the ppd/cups params, the default value
1383 // @return the resulting int
1384 // ----------------------------------------------------
1385 int myGetIntOption( char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, int defaultValue )
1386 {
1387     const char      *val;                   /* CUPS option value */ 
1388     ppd_option_t    *option;                /* PPD option */
1389     
1390     if ( (val = cupsGetOption( optionName, num_options, options)) != NULL)
1391         return  atoi(val);
1392     else if ((option = ppdFindOption(ppd, optionName)) != NULL)
1393         return atoi(option->defchoice);
1394     else
1395         return defaultValue;
1396 }
1397
1398 // ----------------------------------------------------
1399 //  char myGetCharOption( char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, char defaultValue )
1400 //
1401 // @brief get an option (char) - the first char of cups then ppd option then default
1402 // @author fhl
1403 // @param dest :  the name of the option, the ppd/cups params, the default value
1404 // @return the resulting char
1405 // ----------------------------------------------------
1406 char myGetCharOption( char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, char defaultValue )
1407 {
1408     const char      *val;                   /* CUPS option value */ 
1409     ppd_option_t    *option;                /* PPD option */
1410     
1411     if ( (val = cupsGetOption( optionName, num_options, options)) != NULL)
1412         return val[0];
1413     else if ((option = ppdFindOption(ppd, optionName)) != NULL)
1414         return (option->defchoice)[0];
1415     else
1416         return defaultValue;
1417 }
1418
1419 // ----------------------------------------------------
1420 //  char* myGetStrOption( char *dest, char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, const char* defaultStr )
1421 //
1422 // @brief get an option (string) from cups then ppd option then default
1423 // @author fhl
1424 // @param dest : the resulting string, the name of the option, the ppd/cups params, the default value
1425 // @return the resulting string pointer
1426 // ----------------------------------------------------
1427 char* myGetStrOption( char *dest, char* optionName, int num_options, cups_option_t *options, ppd_file_t *ppd, const char* defaultStr )
1428 {
1429     const char      *val;                   /* CUPS option value */ 
1430     ppd_option_t    *option;                /* PPD option */
1431     
1432     if ( (val = cupsGetOption( optionName, num_options, options)) != NULL)
1433         return strcpy(dest, val);
1434     else if ((option = ppdFindOption(ppd, optionName)) != NULL)
1435         return strcpy(dest, option->defchoice);
1436     else
1437         return strcpy(dest, defaultStr);
1438 }
1439
1440 // ----------------------------------------------------
1441 //  int EvolisModelNumberFromPPD( char*  modelname )
1442 //
1443 // @brief see return ... 
1444 // @author fhl
1445 // @param take ppd header model description
1446 // @return number associated to our printer model (see evolis.h)            
1447 // ----------------------------------------------------
1448 int EvolisModelNumberFromPPD( char*  modelname )
1449 {
1450     if      (!strcasecmp(modelname,"EVOLIS Pebble Card Printer"))       return PEBBLE;
1451     else if (!strcasecmp(modelname,"EVOLIS Tattoo Card Printer"))       return TATTOO;
1452     else if (!strcasecmp(modelname,"EVOLIS Quantum Card Printer"))      return QUANTUM;
1453     else if (!strcasecmp(modelname,"EVOLIS Dualys Card Printer"))       return DUALYS;
1454     else if (!strcasecmp(modelname,"EVOLIS Securion Card Printer"))     return SECURION;    // fhl - 11/06/08
1455     else if (!strcasecmp(modelname,"EVOLIS Tattoo2 Card Printer"))      return TATTOO2;     // fhl - 11/06/08 - idem que PEBBLE
1456     else                                                                return PEBBLE;      // fhl - 09/07/08 - default model
1457 }
1458
1459 // ----------------------------------------------------
1460 //  int     SendMagEncodingHeader   ( MagInfo_t* mag );
1461 //
1462 // @brief prepare printer for encoding by sending mag parameters 
1463 // @author fhl
1464 // @return  1 -  ok 
1465 //          0 - nok
1466 // ----------------------------------------------------
1467 int     SendMagEncodingHeader   ( MagInfo_t* mag )
1468 {       
1469     int i;
1470     
1471     if (!(strcasecmp(mag->Coercivity, "HICO")))
1472         output("\033Pmc;h\015");    
1473     else
1474         output("\033Pmc;l\015");
1475     
1476     for ( i=0 ; i<3 ; i++ )
1477     {
1478         output("\033Pmt;%d;%d\015",i+1,mag->Track[i].type);
1479         
1480         if ( mag->Track[i].density == 0 ) // default 
1481         {
1482             if ( mag->Track[i].type == MAGTYPE_C2_75  ) output( "\033Pmd;%d;%d\015", i+1, 75 );
1483             if ( mag->Track[i].type == MAGTYPE_C2_210 ) output( "\033Pmd;%d;%d\015", i+1, 210 );
1484         }
1485         else
1486             output( "\033Pmd;%d;%d\015", i+1, mag->Track[i].density );
1487         
1488         debug( "Mag Density Track%d : %d",  i+1, mag->Track[i].density );
1489     }       
1490     return 1; // no parameters checking ... yet
1491 }
1492
1493 // ----------------------------------------------------
1494 // int      ProcessSpecialCommands  ( const char* cmd, MagInfo_t* mag )
1495 //
1496 // @brief prepare printer for encoding by sending mag parameters 
1497 // @author fhl
1498 // @return  1 -  ok 
1499 //          0 - nok
1500 // ----------------------------------------------------
1501 int     ProcessSpecialCommands  ( const char* cmd, MagInfo_t* mag )
1502 {
1503     int i;
1504     if (!(strcasecmp(cmd, "ISMART")))
1505     {
1506         info("Inserting smart card.");
1507         output("\033Sis\015");
1508     }
1509     else if (!(strcasecmp(cmd, "ICTLESS")))
1510     {
1511         info("Inserting contactless card.");
1512         output("\033Sic\015");
1513     }
1514     else if (!(strcasecmp(cmd, "EJECT")))
1515     {
1516         info("Ejecting card.");
1517         output("\033Se\015");
1518     }
1519     else if (!(strcasecmp(cmd, "REJECT")))
1520     {
1521         info("Rejecting card.");
1522         output("\033Ser\015");
1523     }
1524     else if (!(strcasecmp(cmd, "TEST")))
1525     {
1526         info("Self test card.");
1527         output("\033St\015");
1528     }
1529     else if (!(strcasecmp(cmd, "CLEAN")))
1530     {
1531         info("Self cleaning card.");
1532         output("\033Scp\015");
1533     }
1534     else if (!(strcasecmp(cmd, "AJUST")))
1535     {
1536         info("Self adjusment.");
1537         output("\033Sa\015");
1538     }
1539     else if (!(strcasecmp(cmd, "SELFMAG")))
1540     {
1541         info("Self magnetic test card.");
1542         output("\033Stt;m\015");
1543     }
1544     else if (!(strcasecmp(cmd, "TestTech")))   // fhl - 26/06/08 - ajout
1545     {
1546         info("Technical Test Card");
1547         output("\033Stt\015");
1548     }
1549     else if (!(strcasecmp(cmd, "ONLYENCO")))
1550     {
1551         info("Only encoding.");
1552         
1553         output("\033Ss\015");
1554         for (i=0;i<3;i++)
1555             if( MagInfoCard.Track[i].data[0] ) 
1556             {
1557                 info("Download track %d", i+1);
1558                 output( "%s", MagInfoCard.Track[i].data );
1559             }
1560             
1561         output("\033Smw\015");
1562         if (!mag->KeepCard) 
1563         {
1564             info("Eject card after encoding.");
1565             output("\033Se\015");
1566         }
1567         else 
1568         {
1569             info("Keep card after encoding.");
1570             output("\033Ste\015");
1571         }
1572     }
1573     return 1;  // todo 
1574 }
1575
1576 // ----------------------------------------------------
1577 // int GetLaminationOption( LaminatorOption_t *lam_opt, int num_options, cups_option_t *options, ppd_file_t *ppd )
1578 //
1579 // @brief parse lamination options
1580 // @author fhl
1581 // @return  1 -  ok 
1582 //          0 - nok
1583 // ----------------------------------------------------
1584 int GetLaminationOption( LaminatorOption_t *lam_opt, int num_options, cups_option_t *options, ppd_file_t *ppd )
1585 {
1586     // fhl - 11/06/08 - Parsing Lamination Option : securion        
1587     
1588     lam_opt->defLam = myGetCharOption( "DefLam", num_options, options, ppd, '0' );
1589     
1590     if ( (lam_opt->defLam!='0') && (lam_opt->defLam!='r') && 
1591          (lam_opt->defLam!='v') && (lam_opt->defLam!='b') ) 
1592          lam_opt->defLam='0';           
1593     info("DefLam : %c", lam_opt->defLam);
1594     
1595     lam_opt->exitLam = myGetCharOption( "ExitLam", num_options, options, ppd, '0' );
1596     
1597     if ( (lam_opt->exitLam!='0') && (lam_opt->exitLam!='r') && 
1598          (lam_opt->exitLam!='v') && (lam_opt->exitLam!='b') ) 
1599          lam_opt->exitLam='0'; 
1600     info("ExitLam : %c", lam_opt->exitLam);
1601     
1602     lam_opt->lamType = myGetCharOption( "LamType", num_options, options, ppd, '0' );
1603     
1604     if ( (lam_opt->lamType!='0') && (lam_opt->lamType!='1') && (lam_opt->lamType!='2') ) 
1605         lam_opt->lamType='0'; 
1606     info("LamType : %c", lam_opt->lamType);
1607     
1608     lam_opt->lamAlt = myGetCharOption( "LamAlt", num_options, options, ppd, '0' );
1609     
1610     if ( (lam_opt->lamAlt!='0') && (lam_opt->lamAlt!='1') && (lam_opt->lamAlt!='2') ) 
1611         lam_opt->lamAlt='0'; 
1612     info("LamAlt : %c", lam_opt->lamAlt);
1613     
1614     lam_opt->lamSpeed = myGetIntOption( "LamSpeed", num_options, options, ppd, 4 );
1615     
1616     if ( (lam_opt->lamSpeed<2) && (lam_opt->lamSpeed>18) ) lam_opt->lamSpeed=4; 
1617     info("LamSpeed : %d", lam_opt->lamSpeed);
1618     
1619     lam_opt->lamTemp = myGetIntOption( "Lamtemp", num_options, options, ppd, 155 );
1620     
1621     if ( (lam_opt->lamTemp<100) && (lam_opt->lamTemp>180) ) lam_opt->lamTemp=155;           
1622     info("Lamtemp : %d", lam_opt->lamTemp);
1623     
1624     myGetStrOption( lam_opt->lamDesc, "LamDescription", num_options, options, ppd, "Custom" ); 
1625     
1626     lam_opt->lamDesc[16] = 0; // on place un caractere de fin dans tous les cas au bout du tableau (voir strncpy)
1627     info("LamDescription : %s", lam_opt->lamDesc);
1628     
1629     return 1;
1630 }
1631
1632 // ----------------------------------------------------
1633 // int ProcessPassthroughOption( int num_options, cups_option_t *options, ppd_file_t *ppd )
1634 //
1635 // @brief Process Passthrough options
1636 // @author fhl
1637 // @return  1 -  ok 
1638 //          0 - nok
1639 // ----------------------------------------------------
1640 int ProcessPassthroughOption( int num_options, cups_option_t *options, ppd_file_t *ppd )
1641 {
1642     const char      *val;                   /* CUPS option value */ 
1643     char WtData[MAX_PASSTHROUGH_SZ];
1644     int  i = 0, j = 0;
1645
1646     if ((val = cupsGetOption("RawData", num_options, options)) != NULL) 
1647         strcpy(WtData,val);
1648     else
1649         if ((val = cupsGetOption("passthrough", num_options, options)) != NULL) 
1650             strcpy(WtData,val);
1651         else 
1652             WtData[0] = 0x00;
1653     
1654     j = 0;  i = 0;  
1655     info("*** Passthrough : %s", &WtData[j]);
1656     if (WtData[0] != 0x00) output("\033Wcb;k\015");   // K panel printing Init.
1657
1658     while (WtData[i] != 0x00 && i < MAX_PASSTHROUGH_SZ) 
1659     {
1660         if((WtData[i] == '|') && i) 
1661         {
1662             WtData[i] = 0x00;
1663             output("\033%s\015",&WtData[j]);
1664             info("Passthrough : %s", &WtData[j]);
1665             j=i+1;        
1666         }
1667         i++;
1668     }
1669         if ((i!=j) && (i < MAX_PASSTHROUGH_SZ))  
1670         {       
1671                 // WtData[i] = 0;
1672                 debug("Passthrough : %s", &WtData[j]);
1673                 output("\033%s\015", &WtData[j]);
1674         }
1675     return 1; 
1676
1677 }
1678
1679 // ----------------------------------------------------
1680 // int GetMagOption( LaminatorOption_t *lam_opt, int num_options, cups_option_t *options, ppd_file_t *ppd )
1681 //
1682 // @brief parse Magnetic encoding options
1683 // @author fhl
1684 // @return  1 -  ok 
1685 //          0 - nok
1686 // ----------------------------------------------------
1687 int GetMagOption( MagInfo_t *mag, int num_options, cups_option_t *options, ppd_file_t *ppd )
1688 {
1689     const char      *val;                   /* CUPS option value */ 
1690     char            tmp[10];
1691
1692     myGetStrOption(mag->Coercivity, "Coercivity", num_options, options, ppd, "None" ); 
1693     debug("Coercivity : %s", mag->Coercivity);
1694     
1695     if(strcasecmp(mag->Coercivity,"NONE") || !(strcasecmp(EjectCard, "ONLYENCO")) ) 
1696     {
1697         mag->Track[0].type = myGetIntOption( "Track1", num_options, options, ppd, 1 ); 
1698         mag->Track[1].type = myGetIntOption( "Track2", num_options, options, ppd, 2 ); 
1699         mag->Track[2].type = myGetIntOption( "Track3", num_options, options, ppd, 3 ); 
1700         
1701         debug("Track\t 1: %d\t  2: %d\t  3: %d", mag->Track[0].type,
1702               mag->Track[1].type,
1703               mag->Track[2].type );
1704         
1705         mag->Track[0].density = myGetIntOption( "Density1", num_options, options, ppd, 0 );         
1706         mag->Track[1].density = myGetIntOption( "Density2", num_options, options, ppd, 0 );         
1707         mag->Track[2].density = myGetIntOption( "Density3", num_options, options, ppd, 0 );         
1708         
1709         debug("Density\t 1: %d\t  2: %d\t  3: %d", mag->Track[0].density,
1710               mag->Track[1].density,
1711               mag->Track[2].density );
1712         
1713         myGetStrOption( tmp, "KeepCard", num_options, options, ppd, "True" );           
1714         if ( (tmp[0] == 'F') || (tmp[0] == 'f')) 
1715             mag->KeepCard = 0;
1716         else
1717             mag->KeepCard = 1;
1718         debug("KeepCard : %d", mag->KeepCard);
1719
1720         if ((val = cupsGetOption("Track1Data", num_options, options)) != NULL) 
1721         {
1722             sprintf( mag->Track[0].data, "\033Dm;1;%s\015", val );
1723             info("%s", mag->Track[0].data );
1724         }
1725         else
1726             mag->Track[0].data[0] = 0;
1727         
1728         if ((val = cupsGetOption("Track2Data", num_options, options)) != NULL) 
1729         {
1730             sprintf( mag->Track[1].data, "\033Dm;2;%s\015", val );
1731             info("%s", mag->Track[1].data );
1732         }
1733         else
1734             mag->Track[1].data[0] = 0;
1735         
1736         if ((val = cupsGetOption("Track3Data", num_options, options)) != NULL) 
1737         {
1738             sprintf( mag->Track[2].data, "\033Dm;3;%s\015", val );
1739             info("%s", mag->Track[2].data );
1740         }
1741         else
1742             mag->Track[2].data[0] = 0;
1743                     info("Set Magnetic encoder");
1744         
1745         return SendMagEncodingHeader( mag );
1746     }
1747     return 1;
1748 }
1749
1750 // ----------------------------------------------------
1751 // int GetPageSetupOption( int num_options, cups_option_t *options, ppd_file_t *ppd )
1752 //
1753 // @brief parse page setup options
1754 // @author fhl
1755 // @return  1 -  ok 
1756 //          0 - nok
1757 // ---------------------------------------------------- 
1758 int GetPageSetupOption( int num_options, cups_option_t *options, ppd_file_t *ppd )
1759 {
1760     const char      *val;                   /* CUPS option value */ 
1761
1762     if ((val = cupsGetOption("orientation", num_options, options)) != NULL) 
1763     {
1764         if(!strcasecmp(val,"PORTRAIT")) 
1765             cOrientation = PORTRAIT;
1766         else 
1767             cOrientation = LANDSCAPE;
1768         debug("cOrientation : %d", cOrientation);
1769     }
1770     
1771     if ((val = cupsGetOption("Sides", num_options, options)) != NULL) 
1772     {
1773         if(!strcasecmp(val,"ONE-SIDED")) 
1774             cSides = 0;
1775         else 
1776             cSides = 1;
1777         debug("cSides : %d", cSides);
1778     }
1779     
1780     if ((val = cupsGetOption("page-left", num_options, options)) != NULL) 
1781     {
1782         lMargin = atoi(val);
1783         debug("lMargin : %d", lMargin);
1784     }
1785     
1786     if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
1787     {
1788         tMargin = atoi(val);
1789         debug("tMargin : %d", lMargin);
1790     }
1791     if ((val = cupsGetOption("page-right", num_options, options)) != NULL) 
1792     {
1793         rMargin = atoi(val);
1794         debug("rMargin : %d", lMargin);
1795     }
1796     if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
1797     {
1798         bMargin = atoi(val);
1799         debug("bMargin : %d", lMargin);
1800     }
1801     return 1;
1802 }
1803
1804 // ----------------------------------------------------
1805 // int GetEvolisOption( int num_options, cups_option_t *options, ppd_file_t *ppd )
1806 //
1807 // @brief parse evolis printer options
1808 // @author fhl
1809 // @return  1 -  ok 
1810 //          0 - nok
1811 // ---------------------------------------------------- 
1812 int GetEvolisOption( int num_options, cups_option_t *options, ppd_file_t *ppd )
1813 {
1814     const char      *val;                   /* CUPS option value */ 
1815
1816     myGetStrOption( EjectCard, "EjectCard", num_options, options, ppd, "None" );
1817     debug("EjectCard : %s", EjectCard);
1818     
1819     myGetStrOption( ColorSmooth, "ColorSmooth", num_options, options, ppd, "VeryHigh" );
1820     debug("ColorSmooth : %s", ColorSmooth); // todo fhl : remove comment
1821     
1822     Brightness[RECTO] = myGetIntOption( "Brightness", num_options, options, ppd, 10 );
1823     debug("Brightness (recto) : %d", Brightness[RECTO]);
1824     
1825     Brightness[VERSO] = myGetIntOption( "BrightnessV", num_options, options, ppd, Brightness[RECTO] );
1826     debug("Brightness (verso) : %d", Brightness[VERSO]);
1827     
1828     Contrast[RECTO]  = myGetIntOption( "Contrast", num_options, options, ppd, 10 );
1829     debug("Contrast (recto) : %d", Contrast[RECTO] );
1830     
1831     Contrast[VERSO] = myGetIntOption( "ContrastV", num_options, options, ppd, Contrast[RECTO] );
1832     debug("Contrast (verso)  : %d", Contrast[VERSO]);
1833
1834     SensibilityK[RECTO]  = myGetIntOption( "SensibilityK", num_options, options, ppd, 10 );
1835     debug("SensibilityK (recto) : %d", SensibilityK[RECTO] );
1836     
1837     SensibilityK[VERSO] = myGetIntOption( "SensibilityKV", num_options, options, ppd, SensibilityK[RECTO] );
1838     debug("SensibilityK (verso)  : %d", SensibilityK[VERSO]);
1839
1840     SensibilityO[RECTO]  = myGetIntOption( "SensibilityO", num_options, options, ppd, 10 );
1841     debug("SensibilityO (recto) : %d", SensibilityO[RECTO] );
1842     
1843     SensibilityO[VERSO] = myGetIntOption( "SensibilityOV", num_options, options, ppd, SensibilityO[RECTO] );
1844     debug("SensibilityO (verso)  : %d", SensibilityO[VERSO]);
1845     
1846     myGetStrOption( OverlayPannel, "OverlayPannel", num_options, options, ppd, "FO" );
1847     debug("OverlayPannel : %s", OverlayPannel);
1848     
1849     myGetStrOption( OverlayBackPannel, "OverlayBackPannel", num_options, options, ppd, "FO" );
1850     debug("OverlayBackPannel : %s", OverlayBackPannel);
1851     
1852     overlayRegion[RECTO][0] = myGetIntOption( "TopCover", num_options, options, ppd, 0 );
1853     debug("TB: %d",overlayRegion[RECTO][0]);  
1854     
1855     overlayRegion[RECTO][1] = myGetIntOption( "TopLeft", num_options, options, ppd, 0 );
1856     debug("LB: %d",overlayRegion[RECTO][1]);
1857     
1858     overlayRegion[RECTO][2] = myGetIntOption( "BottomCover", num_options, options, ppd, 0 );
1859     debug("BB: %d",overlayRegion[RECTO][2]);
1860     
1861     overlayRegion[RECTO][3] = myGetIntOption( "BottomRight", num_options, options, ppd, 0 );
1862     debug("RB: %d",overlayRegion[RECTO][3]);
1863     
1864     overlayRegion[RECTO][4] = myGetIntOption( "TopWCover", num_options, options, ppd, 0 );
1865     debug("TW: %d",overlayRegion[RECTO][4]);
1866     
1867     overlayRegion[RECTO][5] = myGetIntOption( "TopWLeft", num_options, options, ppd, 0 );
1868     debug("LW: %d",overlayRegion[RECTO][5]);
1869     
1870     overlayRegion[RECTO][6] = myGetIntOption( "BottomWCover", num_options, options, ppd, 0 );
1871     debug("BW: %d",overlayRegion[RECTO][6]);
1872     
1873     overlayRegion[RECTO][7] = myGetIntOption( "BottomWRight", num_options, options, ppd, 0 );
1874     debug("RW: %d",overlayRegion[RECTO][7]);
1875
1876     overlayRegion[VERSO][0] = myGetIntOption( "TopCoverV", num_options, options, ppd, 0 );
1877     debug("TB: %d",overlayRegion[VERSO][0]);  
1878     
1879     overlayRegion[VERSO][1] = myGetIntOption( "TopLeftV", num_options, options, ppd, 0 );
1880     debug("LB: %d",overlayRegion[VERSO][1]);
1881     
1882     overlayRegion[VERSO][2] = myGetIntOption( "BottomCoverV", num_options, options, ppd, 0 );
1883     debug("BB: %d",overlayRegion[VERSO][2]);
1884     
1885     overlayRegion[VERSO][3] = myGetIntOption( "BottomRightV", num_options, options, ppd, 0 );
1886     debug("RB: %d",overlayRegion[VERSO][3]);
1887     
1888     overlayRegion[VERSO][4] = myGetIntOption( "TopWCoverV", num_options, options, ppd, 0 );
1889     debug("TW: %d",overlayRegion[VERSO][4]);
1890     
1891     overlayRegion[VERSO][5] = myGetIntOption( "TopWLeftV", num_options, options, ppd, 0 );
1892     debug("LW: %d",overlayRegion[VERSO][5]);
1893     
1894     overlayRegion[VERSO][6] = myGetIntOption( "BottomWCoverV", num_options, options, ppd, 0 );
1895     debug("BW: %d",overlayRegion[VERSO][6]);
1896     
1897     overlayRegion[VERSO][7] = myGetIntOption( "BottomWRightV", num_options, options, ppd, 0 );
1898     debug("RW: %d",overlayRegion[VERSO][7]);
1899     
1900     BlackIn[RECTO] = myGetCharOption( "BlackIn", num_options, options, ppd, 'N' );
1901     info/*debug*/("BlackIn (recto) : %c", BlackIn[RECTO]);
1902     
1903     BlackIn[VERSO] = myGetCharOption(  "BlackInV", num_options, options, ppd, 'N' );
1904     info/*debug*/("BlackIn (verso) : %c", BlackIn[VERSO]);
1905     
1906     TreatementK[RECTO] = myGetCharOption( "TreatementK", num_options, options, ppd, 'G' );
1907     debug("TreatementK (recto) : %c", TreatementK[RECTO]);
1908     
1909     TreatementK[VERSO] = myGetCharOption(  "TreatementKV", num_options, options, ppd, 'G' );
1910     debug("TreatementK (verso) : %c", TreatementK[VERSO]);
1911     
1912     QualityK = myGetIntOption( "QualityK", num_options, options, ppd, 0 );
1913     debug("QualityK : %d", QualityK);
1914     
1915     // fhl - option retiree des ppds - 26/06/08
1916     //          concerne la detection auto du debut d'impression quand ymckos
1917     
1918     DetectAuto = myGetIntOption( "DetectAuto", num_options, options, ppd, 1);   
1919     debug("DetectAuto : %d", DetectAuto);
1920     
1921     StartDist = myGetIntOption( "StartDist", num_options, options, ppd, 0) * 12;    
1922     debug("StartDist : %d", StartDist);
1923     
1924     myGetStrOption( Soften, "Soften", num_options, options, ppd, "FALSE" ); 
1925     // fhl - 30/06/08 - option retiree de l'interface ppd 
1926     //                  FALSE active l'option (augmentation de la qualite de l'image)
1927     debug("Soften : %s", Soften);
1928     
1929     return 1;
1930 }
1931
1932 // ----------------------------------------------------
1933 // int      SetOverlayRegion        ( int overlayRegion[8] )
1934 //
1935 // @brief swap overlay region description 
1936 // @author fhl
1937 // @return  1 -  ok 
1938 //          0 -  nok
1939 // ----------------------------------------------------
1940 int     SetOverlayRegion        ( int region[8] )
1941 {
1942     TB = region[0];
1943     LB = region[1];
1944     BB = region[2];
1945     RB = region[3];
1946     TW = region[4];
1947     LW = region[5];
1948     BW = region[6];
1949     RW = region[7];
1950     
1951     return 1;
1952 }
1953 /* End of rastertoevolis.c,v 2.0*/
1954