Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpijs / ljjetready.cpp
1 /*****************************************************************************\
2   ljjetready.cpp : Implimentation for the LJJetReady class
3
4   Copyright (c) 1996 - 2008, Hewlett-Packard Co.
5   All rights reserved.
6
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10   1. Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12   2. Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15   3. Neither the name of Hewlett-Packard nor the names of its
16      contributors may be used to endorse or promote products derived
17      from this software without specific prior written permission.
18
19   THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
22   NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24   TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \*****************************************************************************/
30
31
32 #ifdef APDK_LJJETREADY
33 /*
34  *  Not sure need HAVE_PROTOTYPES here, a user reported a compiler error under Tru64. The error
35  *  was for the assignment jerr.error_exit = Gjpeg_error; This seems to be due to JMETHOD
36  *  definition in jmorecfg.h
37  */
38
39 //#define HAVE_PROTOTYPES
40
41 #include "header.h"
42 #include "io_defs.h"
43 #include "ljjetready.h"
44 #include "printerproxy.h"
45 #include "resources.h"
46
47 #ifdef HAVE_LIBDL
48 #include <dlfcn.h>
49 #endif
50
51 extern "C"
52 {
53 int (*HPLJJRCompress) (BYTE       *pbOutBuffer, 
54                        uint32_t   *outlen, 
55                        BYTE       *inmem, 
56                        const uint32_t iLogicalImageWidth,
57                        const uint32_t iLogicalImageHeight);
58 }
59
60 APDK_BEGIN_NAMESPACE
61
62 #ifdef HAVE_LIBDL
63 extern void *LoadPlugin (const char *szPluginName);
64 #endif
65
66 extern MediaSize PaperToMediaSize(PAPER_SIZE psize);
67
68 #define MOJAVE_STRIP_HEIGHT     128 // Mojave strip height should always be 128 for compression sake
69
70 #define MOJAVE_RESOLUTION       600 // Mojave supports only one resolution- 600 DPI     
71
72 BYTE JrBeginSessionSeq[]                                = {0xC0, 0x00, 0xF8, 0x86, 0xC0, 0x03, 0xF8, 0x8F, 0xD1, 0x58, 
73                                                                                     0x02, 0x58, 0x02, 0xF8, 0x89, 0x41};
74 BYTE JrFeedOrientationSeq[]                             = {0xC0, 0x00  , 0xF8, 0x28 };
75 //                                                                                         |fd ori enum|       |ori cmd|                                                                                        
76 BYTE JrPaperSizeSeq[]                                   = {0xC0,  0x00      ,0xF8, 0x25};
77 //                                                                                         |pap siz enum|     |pap sz cmd|
78 BYTE JrMedSourceSeq[]                                   = {0xC0,  0x00      ,0xF8, 0x26        };
79 //                                                                                         |Med src enum|     |Med src cmd|
80 BYTE JrMedDestinationSeq[]                              = {0xC0,  0x00        ,0xF8 , 0x24        };
81 //                                                                                         |Med Dest enum|      |Med src cmd|
82 BYTE JrBeginPageSeq[]                               = {0x43, 0xD3, 0x64, 0x00, 0x64, 0x00, 0xF8, 0x2A, 0x75, 0xD3, 
83                                                                                     0x00, 0x00, 0x00, 0x00, 0xF8, 0x4C, 0x6B};
84 BYTE JrBeginImageSeq[]                              = {0xC2, 0x00, 0x40, 0x70, 0x68, 0xF8, 0x91, 0xC1};
85
86 BYTE JrVU_ver_TagSeq[]                                  = {0xC2, 0x00, 0x00, 0x04, 0x00 , 0xF8, 0x95                      };
87 //                                                                                              |endian alignd         |  |Jr_ver_ tag|
88 BYTE JrDataLengthSeq[]                                  = {0xC2, 0x86, 0x0A, 0x00, 0x00, 0xF8, 0x92       };
89 //                                                                                                                                                        | VU data length|
90 BYTE JrVenUniqSeq[]                                             = {0x46};
91 BYTE JrVUExtn_3Seq[]                                    = {0xC2, 0x02, 0x40, 0x70, 0x68                 ,0xF8, 0x91     };
92 //                                                                                              |endian alignd Jr rd img tag|     |VU extensn|
93 BYTE JrEndPageSeq[]                                             =  {0x44};
94 BYTE JrEndSessionSeq[]                                  =  {0x42};
95 // PJL level commands..
96
97 //**JETLIB ENTRIES
98 const char ccpPJLStartJob[]                             = {ESC, '%', '-','1','2','3','4','5','X' };;
99 const char ccpPJLExitSeq[]                              = {ESC, '%', '-','1','2','3','4','5','X', '@','P','J','L',' ','E','O','J', LF, ESC,'%', '-','1','2','3','4','5','X'};
100 const char ccpPJLSetRes[]                               = {'@','P','J','L',' ','S','E','T',' ','R','E','S','O','L','U','T','I','O','N','=','6','0','0', LF};
101 const char ccpPJLUTF8[]                                 = {'@','P','J','L',' ','S','E','T',' ','S','T','R','I','N','G','C','O','D','E','S','E','T','=','U','T','F','8', LF};
102 const char ccpPJLSetPlanes[]                    = {'@','P','J','L',' ','S','E','T',' ','P','L','A','N','E','S','I','N','U','S','E','=','1',LF}; //Sent only for GrayScale Printing
103 const char ccpPCLEnterXL[]                              = {'@','P','J','L',' ','E','N','T','E','R',' ','L','A','N','G','U','A','G','E','=','P','C','L','X','L', LF};
104 const char ccpPJLSetTO[]                                = {'@','P','J','L',' ','S','E','T',' ','T','I','M','E','O','U','T','=','9','0', LF};
105 const char ccpPJLSetCopyCount[]                 = {'@','P','J','L',' ','S','E','T',' ','C','O','P','I','E','S','=','1',LF};
106 const char ccpUEL[]                     = {ESC, '%', '-','1','2','3','4','5','X' };
107 const char ccpPJLComment[]                              = {')',' ','H','P','-','P','C','L',' ','X','L',';','3',';','0',';','C','o','m','m','e','n','t',',',' ','P','C','L','-','X','L',' ','J','e','t','R','e','a','d','y',' ','g','e','n','e','r','a','t','o','r', LF};
108 //**END JETLIB ENTRIES
109
110
111 LJJetReady::LJJetReady (SystemServices* pSS, int numfonts, BOOL proto)
112     : Printer(pSS, numfonts, proto)
113 {
114
115     if ((!proto) && (IOMode.bDevID))
116     {
117         constructor_error = VerifyPenInfo();
118         CERRCHECK;
119     }
120     else ePen = BOTH_PENS;    // matches default mode
121         
122     pMode[GRAYMODE_INDEX]      = new LJJetReadyGrayMode ();
123     pMode[DEFAULTMODE_INDEX]   = new LJJetReadyNormalMode ();
124     ModeCount = 2;
125
126
127     CMYMap = NULL;
128     m_bJobStarted = FALSE;
129 #ifdef  APDK_AUTODUPLEX
130     m_bRotateBackPage = FALSE;  // Lasers don't require back side image to be rotated
131 #endif
132     m_pCompressor = NULL;
133     m_iYPos = 0;
134
135         m_bStartPageNotSent = TRUE;
136
137     HPLJJRCompress = NULL;
138
139 #ifdef HAVE_LIBDL
140     m_hHPLibHandle = LoadPlugin ("lj.so");
141     if (m_hHPLibHandle)
142     {
143         dlerror ();
144         *(void **) (&HPLJJRCompress) = dlsym (m_hHPLibHandle, "HPJetReadyCompress");
145     }
146     if (HPLJJRCompress)
147     {
148         pMode[ModeCount] = new LJJetReadyBestColorMode ();
149         ModeCount++;
150         pMode[ModeCount] = new LJJetReadyBestGrayMode ();
151         ModeCount++;
152     }
153 #endif
154     m_eCompressMode = COMPRESS_MODE_JPEG;
155
156     DBG1("LJJetReady created\n");
157 }
158
159 LJJetReady::~LJJetReady ()
160 {
161     DISPLAY_STATUS  eDispStatus;
162
163 #ifdef HAVE_LIBDL
164     if (m_hHPLibHandle)
165     {
166         dlclose (m_hHPLibHandle);
167     }
168 #endif
169
170     if (IOMode.bStatus && m_bJobStarted)
171     {
172         for (int i = 0; i < 5; i++)
173         {
174             pSS->BusyWait (2000);
175             eDispStatus = ParseError (0);
176             if (eDispStatus == DISPLAY_PRINTING_COMPLETE)
177             {
178                 pSS->DisplayPrinterStatus (eDispStatus);
179                 break;
180             }
181         }
182     }
183 }
184
185 LJJetReadyNormalMode::LJJetReadyNormalMode ()
186 : PrintMode (NULL)
187 {
188     ResolutionX[0] = 600;
189     ResolutionY[0] = 600;
190     BaseResX = BaseResY = 600;
191
192     bFontCapable = FALSE;
193
194 #if defined(APDK_VIP_COLORFILTERING)
195     Config.bErnie = FALSE;
196 #endif
197     Config.bColorImage = FALSE;
198         theQuality = qualityNormal;
199
200     pmQuality = QUALITY_NORMAL;
201         Config.bColorImage = FALSE;
202 #ifdef APDK_AUTODUPLEX
203     bDuplexCapable = TRUE;
204 #endif
205 }
206
207 LJJetReadyBestColorMode::LJJetReadyBestColorMode () : PrintMode (NULL)
208 {
209     ResolutionX[0] =
210     ResolutionY[0] =
211     BaseResX =
212     BaseResY = 600;
213
214     bFontCapable = FALSE;
215
216 #if defined(APDK_VIP_COLORFILTERING)
217     Config.bErnie = FALSE; // Raghu
218 #endif
219
220     Config.bColorImage = FALSE;
221     theQuality = qualityPresentation;
222     pmQuality = QUALITY_BEST;
223 #ifdef APDK_AUTODUPLEX
224     bDuplexCapable = TRUE;
225 #endif
226 }
227
228 LJJetReadyGrayMode::LJJetReadyGrayMode () : PrintMode (NULL)
229 {
230     ResolutionX[0] =
231     ResolutionY[0] =
232     BaseResX =
233     BaseResY = 600;
234
235     bFontCapable = FALSE;
236
237 #if defined(APDK_VIP_COLORFILTERING)
238     Config.bErnie = FALSE; // Raghu
239 #endif
240
241     Config.bColorImage = FALSE;
242     pmColor = GREY_K;
243 #ifdef APDK_AUTODUPLEX
244     bDuplexCapable = TRUE;
245 #endif
246 }
247
248 LJJetReadyBestGrayMode::LJJetReadyBestGrayMode () : PrintMode (NULL)
249 {
250     ResolutionX[0] =
251     ResolutionY[0] =
252     BaseResX =
253     BaseResY = 600;
254
255     bFontCapable = FALSE;
256
257 #if defined(APDK_VIP_COLORFILTERING)
258     Config.bErnie = FALSE; // Raghu
259 #endif
260
261     Config.bColorImage = FALSE;
262     pmColor = GREY_K;
263     pmQuality = QUALITY_BEST;
264     theQuality = qualityPresentation;
265 #ifdef APDK_AUTODUPLEX
266     bDuplexCapable = TRUE;
267 #endif
268 }
269
270 HeaderLJJetReady::HeaderLJJetReady (Printer* p, PrintContext* pc)
271     : Header(p,pc)
272
273         SetLastBand(FALSE);
274 }
275
276 DRIVER_ERROR HeaderLJJetReady::Send ()
277 {
278     StartSend ();
279
280     return NO_ERROR;
281 }
282
283 DRIVER_ERROR HeaderLJJetReady::StartSend ()
284 {
285     DRIVER_ERROR err;
286     char    szScratchStr[64];
287
288     err = thePrinter->Send ((const BYTE*)ccpPJLStartJob,        sizeof(ccpPJLStartJob));
289     ERRCHECK;
290
291     //Send the UTF8 encoding command
292     err = thePrinter->Send ((const BYTE*)ccpPJLUTF8, sizeof(ccpPJLUTF8));
293     ERRCHECK;
294
295     // If it is Grayscale printjob, send the PJL command indicating the same
296     COLORMODE       eC = COLOR;
297     MEDIATYPE       eM;
298     QUALITY_MODE    eQ;
299     BOOL            bD;
300
301     ((LJJetReady *)thePrinter)->bGrey_K = FALSE;
302     if ((thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD)) == NO_ERROR &&
303         eC == GREY_K)
304     {
305         ((LJJetReady *)thePrinter)->bGrey_K = TRUE;
306         err = thePrinter->Send ((const BYTE*)ccpPJLSetPlanes,sizeof(ccpPJLSetPlanes));
307         ERRCHECK;
308     }
309         
310     //Send the Number of copies command
311 //    err = thePrinter->Send ((const BYTE*)ccpPJLSetCopyCount,sizeof(ccpPJLSetCopyCount));
312     sprintf (szScratchStr, "@PJL SET COPIES=%d\015\012", thePrintContext->GetCopyCount ());
313     err = thePrinter->Send ((const BYTE *) szScratchStr, strlen (szScratchStr));
314     ERRCHECK;
315
316     // Send the Duplex command
317     strcpy (szScratchStr, "@PJL SET DUPLEX=OFF\015\012");
318 #ifdef APDK_AUTODUPLEX\r
319     DUPLEXMODE  dupmode = thePrintContext->QueryDuplexMode ();
320     if (dupmode != DUPLEXMODE_NONE)
321     {
322         strcpy (szScratchStr, "@PJL SET DUPLEX=ON\015\012@PJL SET BINDING=");\r
323         if (dupmode == DUPLEXMODE_BOOK)\r
324             strcat (szScratchStr, "LONGEDGE\015\012");\r
325         else\r
326             strcat (szScratchStr, "SHORTEDGE\015\012");
327     }\r
328 #endif
329     err = thePrinter->Send ((const BYTE *) szScratchStr, strlen (szScratchStr));
330     ERRCHECK;
331
332     //Set the resolution to 600
333     err = thePrinter->Send ((const BYTE*)ccpPJLSetRes,sizeof(ccpPJLSetRes));
334     ERRCHECK;
335
336     //Send the time out command
337     err = thePrinter->Send ((const BYTE*)ccpPJLSetTO,sizeof(ccpPJLSetTO));
338     ERRCHECK;
339
340     //send the mojave PCL_XL_ENTER_LANG command
341     err = thePrinter->Send ((const BYTE*)ccpPCLEnterXL,sizeof(ccpPCLEnterXL));
342     ERRCHECK;
343
344     //send the comment string
345     err = thePrinter->Send ((const BYTE*)ccpPJLComment,sizeof(ccpPJLComment));
346     ERRCHECK;
347
348     err = thePrinter->Send ((const BYTE*)JrBeginSessionSeq,sizeof(JrBeginSessionSeq));
349     ERRCHECK;
350
351     return err;
352 }
353
354 int HeaderLJJetReady::JRPaperToMediaSize(PAPER_SIZE psize)
355 {
356     switch(psize)
357     {
358         case LETTER:            return 0;
359         case LEGAL:             return 1;
360         case A4:                return 2;
361         case B4:                return 10;
362         case B5:                return 11;
363         case OUFUKU:            return 14;
364         case HAGAKI:            return 14;
365         case A6:                return 17;
366 #ifdef APDK_EXTENDED_MEDIASIZE
367         case A3:                return 5;
368         case A5:                return 16;
369         case LEDGER:            return 4;
370         case EXECUTIVE:         return 3;
371         case CUSTOM_SIZE:       return 96;
372         case ENVELOPE_NO_10:    return 6;
373         case ENVELOPE_A2:       return 6;
374         case ENVELOPE_C6:       return 8;
375         case ENVELOPE_DL:       return 9;
376 #endif
377         default:                return 0;
378     }
379 }
380
381 DRIVER_ERROR HeaderLJJetReady::StartPage ()
382 {
383     DRIVER_ERROR err;
384     BYTE    szCustomSize[64];
385
386         /* Orienatation: is JrFeedOrientationSeq[1]. Can take the following values:
387                 Portrait                                : 0x00
388                 Landscape:                              : 0x01
389                 Reversed    Portrait    : 0x02
390                 Reversed    Landscape   : 0x03
391                 Image           Orientataion: 0x04
392                 
393                 Mojave  supports only one feed orientation: Portrait
394         */
395         err = thePrinter->Send ((const BYTE*)JrFeedOrientationSeq,sizeof(JrFeedOrientationSeq));
396         ERRCHECK;
397
398         // Paper Size
399         PAPER_SIZE ps = thePrintContext->GetPaperSize ();
400         int msizeCode;
401     msizeCode = JRPaperToMediaSize(ps); 
402         //Put the papersize into the JrPaperSizeSeq[]
403         JrPaperSizeSeq[1] = (BYTE) msizeCode; 
404 #ifdef APDK_EXTENDED_MEDIASIZE
405         if(msizeCode == 96) //Custom paper size
406         {
407         BYTE    szScratchStr[] = {"\xF8\x2F\xC0\x00\xF8\x30"};
408         union
409         {
410             float       fValue;
411             uint32_t    uiValue;
412         } LJJRUnion;
413         uint32_t    uiXsize;
414         uint32_t    uiYsize;
415         int         k = 0;
416         LJJRUnion.fValue = (float) thePrintContext->PhysicalPageSizeX ();
417         uiXsize = LJJRUnion.uiValue;
418         LJJRUnion.fValue = (float) thePrintContext->PhysicalPageSizeY ();
419         uiYsize = LJJRUnion.uiValue;
420         szCustomSize[k++] = 0xD5;
421         szCustomSize[k++] = (BYTE) (uiXsize & 0x000000FF);
422         szCustomSize[k++] = (BYTE) ((uiXsize & 0x0000FF00) >> 8);
423         szCustomSize[k++] = (BYTE) ((uiXsize & 0x00FF0000) >> 16);
424         szCustomSize[k++] = (BYTE) ((uiXsize & 0xFF000000) >> 24);
425         szCustomSize[k++] = (BYTE) (uiYsize & 0x000000FF);
426         szCustomSize[k++] = (BYTE) ((uiYsize & 0x0000FF00) >> 8);
427         szCustomSize[k++] = (BYTE) ((uiYsize & 0x00FF0000) >> 16);
428         szCustomSize[k++] = (BYTE) ((uiYsize & 0xFF000000) >> 24);
429         err = thePrinter->Send ((const BYTE *) szCustomSize, k);
430
431         err = thePrinter->Send (szScratchStr, sizeof (szScratchStr));
432                 ERRCHECK;
433         }       
434         else
435 #endif
436         {
437                 err = thePrinter->Send ((const BYTE*)JrPaperSizeSeq,sizeof(JrPaperSizeSeq));
438                 ERRCHECK;
439         }
440
441         // If it is Grayscale printjob, send the PJL command indicating the same
442     COLORMODE       eC = COLOR;
443     MEDIATYPE       eM;
444     QUALITY_MODE    eQ;
445     BOOL            bD;
446
447     thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD);
448
449 /*
450  *  Send Printable Area. This is necessary in case source width is less than printable width.
451  *
452  * 
453  *  width is imagewidth - multiple of 96
454  *  height is physical page height - margins for 8x5 x 11 - 6600 - 200 = 6400
455  */
456
457     BYTE    szPrintableArea[] = {"\xD1\x00\x00\x00\x00\xF8\x74"};
458     int     iWidth = (int) thePrintContext->InputPixelsPerRow ();
459     int     iPageHeight;
460
461 /*
462  *  There is a firmware bug in Mojave and Lakota that causes image replicatin across the
463  *  page if width is less than the printable width in grayscale. So, set width to printable
464  *  width for grayscale.
465  */
466
467     if (eC == GREY_K)
468     {
469         iWidth = (int) (thePrintContext->PrintableWidth () *
470                         thePrintContext->EffectiveResolutionX ());
471     }
472
473 /*
474  *  The minimum printable width is 1600 pixels (3 inch * 600 - 200 for margins)
475  */
476
477     if (iWidth < 1600)
478     {
479         iWidth = 1600;
480     }
481
482 /*
483  *  Further, source width must be a multiple of 32.
484  */
485
486
487     iWidth = ((iWidth + 31) / 32) * 32;
488
489     iPageHeight = (int) (thePrintContext->PrintableHeight () *
490                          thePrintContext->EffectiveResolutionY ());
491     iPageHeight = ((iPageHeight + (MOJAVE_STRIP_HEIGHT - 1)) / MOJAVE_STRIP_HEIGHT) * MOJAVE_STRIP_HEIGHT;
492
493     szPrintableArea[1] = iWidth & 0xFF;
494     szPrintableArea[2] = (iWidth >> 8) & 0xFF;
495     szPrintableArea[3] = iPageHeight & 0xFF;
496     szPrintableArea[4] = (iPageHeight >> 8) & 0xFF;
497     err = thePrinter->Send (szPrintableArea, 7);
498     ERRCHECK;
499
500         //MapPCLMediaTypeToString (eM);  // Optional.  No need to send
501
502         err = thePrinter->Send ((const BYTE *)JrBeginPageSeq, sizeof(JrBeginPageSeq));
503         ERRCHECK;
504
505         // The colorspace command has to be sent to intimate the printer to switch to color/monochrome 
506         // depending upon the data that we are about to send.
507         // This command must be sent after SetCursor and before beginimage command
508         if (eC == GREY_K )
509         {
510                 // indicates switch to monochrome mode 
511                 err = thePrinter->Send ((const BYTE *) "\xC0\x07\xF8\x03\x6A", 5);
512                 ERRCHECK;
513         }
514         else
515         {
516                 // indicates switch Color mode
517                 err = thePrinter->Send ((const BYTE *) "\xC0\x06\xF8\x03\x6A", 5);
518                 ERRCHECK;
519         }
520
521         bLastBand = FALSE;
522
523     return err;
524 }
525
526 DRIVER_ERROR HeaderLJJetReady::EndPage ()
527 {
528     DRIVER_ERROR err;
529
530         err = thePrinter->Send ((const BYTE*)JrVUExtn_3Seq,sizeof(JrVUExtn_3Seq));
531         ERRCHECK;
532         err = thePrinter->Send ((const BYTE*)JrVU_ver_TagSeq,sizeof(JrVU_ver_TagSeq));
533         ERRCHECK;
534         err = thePrinter->Send ((const BYTE*)JrVenUniqSeq,sizeof(JrVenUniqSeq));
535         ERRCHECK;
536         err = thePrinter->Send ((const BYTE*)JrEndPageSeq,sizeof(JrEndPageSeq));
537         ERRCHECK;
538
539     return err;
540 }
541
542
543 //-----------------------------------------------------------------------------
544 // Function:    CDJPcl::MapPCLMediaTypeToString()
545 //
546 // Description: Sends the command for mediatype.
547 // Input:       None
548 // Modifies:    None
549 //
550 // Precond:     None
551 //              
552 //                 
553 // Postcond:    The mediatype commands are sent
554 //
555 // Returns:     None
556 //
557 //-----------------------------------------------------------------------------
558 DRIVER_ERROR HeaderLJJetReady::MapPCLMediaTypeToString (MEDIATYPE eM)
559 {
560     DRIVER_ERROR    err;
561     BYTE            szPlain[] = {"\xC8\xC1\x05\x00Plain\xF8\x27"};
562     BYTE            szPhoto[] = {"\xC8\xC1\x05\x00Gloss\xF8\x27"};
563
564     switch (eM)
565     {
566         case (MEDIA_PLAIN):
567             err = thePrinter->Send (szPlain, sizeof (szPlain));
568             ERRCHECK;
569             break;
570
571         case (MEDIA_PHOTO):
572             err = thePrinter->Send (szPhoto, sizeof (szPhoto));
573             ERRCHECK;
574             break;
575         default:
576             //** unsupported media type; return error code
577             assert (0);
578                         err = SYSTEM_ERROR;
579             break;// to be verified..
580     }
581
582     return err; 
583 }
584
585 DRIVER_ERROR HeaderLJJetReady::EndJob ()
586 {
587     DRIVER_ERROR    err = NO_ERROR;
588
589         err = thePrinter->Send((const BYTE*)JrEndSessionSeq, sizeof(JrEndSessionSeq));
590         ERRCHECK;
591
592         err = thePrinter->Send((const BYTE*)ccpPJLExitSeq, sizeof(ccpPJLExitSeq));
593         ERRCHECK;
594
595     return err;
596 }
597
598 DRIVER_ERROR HeaderLJJetReady::FormFeed ()
599 {
600         DRIVER_ERROR    err = NO_ERROR;
601     ModeJPEG        *pCompressor;
602     LJJetReady      *thisPrinter = (LJJetReady *) thePrinter;
603     int             iPageHeight;
604
605     iPageHeight = (int) (thePrintContext->PrintableHeight () *
606                          thePrintContext->EffectiveResolutionY ());
607     iPageHeight = ((iPageHeight + MOJAVE_STRIP_HEIGHT - 1) / MOJAVE_STRIP_HEIGHT) * MOJAVE_STRIP_HEIGHT;
608
609 /*
610  *  Send white rasters to fill up the rest of the page.
611  *  This is required according to Brian Mayer, but introduces a long delay
612  *  in printing. LJ3500 works fine without these white strips.
613  */
614
615     pCompressor = (ModeJPEG *) thisPrinter->GetCompressor ();
616     err = pCompressor->SendWhiteStrips (iPageHeight, thisPrinter->bGrey_K);
617
618
619         bLastBand = TRUE;
620
621         err = EndPage ();
622
623     thisPrinter->m_bStartPageNotSent = TRUE;
624         return err;
625 }
626
627 DRIVER_ERROR HeaderLJJetReady::SendCAPy (unsigned int iAbsY)
628 {
629     return NO_ERROR;
630 }
631
632 DRIVER_ERROR LJJetReady::Encapsulate (const RASTERDATA* InputRaster, BOOL bLastPlane)
633 {
634     BYTE            res[64];
635     BYTE            *pDataPtr = NULL;
636     DRIVER_ERROR    err;
637
638     //if (m_bStartPageNotSent)
639     //{
640     //    err = phLJJetReady->StartPage ();
641     //    if (err != NO_ERROR)
642     //        return err;
643         //      m_bStartPageNotSent = FALSE;
644     //}
645
646
647     unsigned short int   wCoordinate; 
648
649     unsigned long   ulVUDataLength = 0;
650
651         // For color JPEG, you need to skip the header information of 623 bytes
652
653     int iJpegHeaderSize = 623;
654 #ifdef HAVE_LIBDL
655     if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
656     {
657         iJpegHeaderSize = 0;
658     }
659 #endif
660
661         if (bGrey_K)
662     {
663                 ulVUDataLength = InputRaster->rastersize[COLORTYPE_COLOR];
664         pDataPtr = (BYTE *) InputRaster->rasterdata[COLORTYPE_COLOR];
665     }
666         else
667         {
668                 ulVUDataLength = InputRaster->rastersize[COLORTYPE_COLOR]    - iJpegHeaderSize;
669         pDataPtr = (BYTE *) InputRaster->rasterdata[COLORTYPE_COLOR] + iJpegHeaderSize;
670         }
671
672
673     //VWritePrinter("\xC2\x01\x40\x70\x68\xF8\x91\xC1", 0x08);
674         BYTE JrReadImageSeq[] = {0xC2, 0x01, 0x40, 0x70,0x68, 0xF8, 0x91, 0xC1};
675         err = Send ((const BYTE *)JrReadImageSeq, sizeof(JrReadImageSeq));
676         ERRCHECK;
677
678         ModeJPEG     *pCompressor = NULL;
679         pCompressor = (ModeJPEG*)GetCompressor();
680
681     wCoordinate = (unsigned short int)pCompressor->GetCoordinates() - 128;
682 //      err = Send ((const BYTE *)&wCoordinate, sizeof(unsigned short int));
683     res[0] = wCoordinate & 0xFF;
684     res[1] = ((wCoordinate & 0xFF00) >> 8);
685     err = Send ((const BYTE *) res, 2);
686         ERRCHECK;
687
688         BYTE JrStripHeight[] = {0xF8,0x6D,0xC1,0x80,0x00,0xF8,0x63};
689         err = Send ((const BYTE *)JrStripHeight, sizeof(JrStripHeight));
690         ERRCHECK;
691
692         BYTE JrTextObjectTypeSeq[] = {0xC0,0x00, 0xF8, 0x96};
693         err = Send ((const BYTE *)JrTextObjectTypeSeq, sizeof(JrTextObjectTypeSeq));
694         ERRCHECK;
695
696         err = Send ((const BYTE *)JrVU_ver_TagSeq, sizeof(JrVU_ver_TagSeq));
697         ERRCHECK;
698
699         err = Send ((const BYTE *) "\xC2", 1);
700         ERRCHECK;
701
702     ulVUDataLength += 6;
703     res[0] = (BYTE) (ulVUDataLength & 0xFF);
704     res[1] = (BYTE) ((ulVUDataLength & 0x0000FF00) >> 8);
705     res[2] = (BYTE) ((ulVUDataLength & 0x00FF0000) >> 16);
706     res[3] = (BYTE) ((ulVUDataLength & 0xFF000000) >> 24);
707     res[4] = 0xF8;
708     res[5] = 0x92;
709     res[6] = 0x46;
710     res[7] = 0x21;
711 #ifdef HAVE_LIBDL
712     if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
713     {
714         res[7] = 0x11;
715     }
716 #endif
717     res[8] = 0x90;
718
719     ulVUDataLength -= 6;
720     res[9] = (BYTE) (ulVUDataLength & 0xFF);
721     res[10] = (BYTE) ((ulVUDataLength & 0x0000FF00) >> 8);
722     res[11] = (BYTE) ((ulVUDataLength & 0x00FF0000) >> 16);
723     res[12] = (BYTE) ((ulVUDataLength & 0xFF000000) >> 24);
724
725         err = Send (res, 13);
726         ERRCHECK;
727
728         err = Send (pDataPtr, ulVUDataLength);
729         ERRCHECK;
730
731     return err;
732 }
733
734 Header* LJJetReady::SelectHeader (PrintContext *pc)
735 {
736
737 /*
738  *  To take care of what seems to be a firmware bug in the printer's grayscale path,
739  *  need printable width value later. So, save the PrintContext here.
740  *  Raghu
741  */
742
743     COLORMODE       eC = COLOR;
744     MEDIATYPE       eM;
745     QUALITY_MODE    eQ;
746     BOOL            bD;
747
748     thePrintContext = pc;
749     phLJJetReady = new HeaderLJJetReady (this, pc);
750     pc->GetPrintModeSettings (eQ, eM, eC, bD);
751     if (eQ == QUALITY_BEST)
752     {
753         m_eCompressMode = COMPRESS_MODE_LJ;
754     }
755
756 #ifdef HAVE_LIBDL
757     if (HPLJJRCompress && m_eCompressMode != COMPRESS_MODE_LJ)
758     {
759         dlclose (m_hHPLibHandle);
760         m_hHPLibHandle = NULL;
761         HPLJJRCompress = NULL;
762     }
763 #endif
764         return phLJJetReady;
765 }
766
767 DRIVER_ERROR LJJetReady::VerifyPenInfo()
768 {
769     ePen = BOTH_PENS;
770     return NO_ERROR;
771 }
772
773 DRIVER_ERROR LJJetReady::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
774 {
775     ePen = BOTH_PENS;
776
777     return NO_ERROR;
778 }
779
780 Compressor* LJJetReady::CreateCompressor (unsigned int RasterSize)
781 {
782
783 /*
784  *  There is some problem printing in grayscale. When the inputwidth is less than the full
785  *  page width, printer replicates the image across the width. To fix this, make the width of
786  *  each strip the width of the printable page size. Note that this does not create any scaling
787  *  of the image.
788  *  In addition, there is a minimum source width requirement, which is
789  *      3 in. * resolution - 2 * margins = 3 * 600 - 2 * 100 = 1600
790  *  So, minimum RasterSize must be 1600 * 3 here (width * 3 for RGB).
791  *  Raghu
792  */
793
794     if (bGrey_K)
795     {
796         RasterSize = (int) (thePrintContext->PrintableWidth () * thePrintContext->EffectiveResolutionX ()) * 3;
797     }
798
799     if (RasterSize < 4800)
800     {
801         RasterSize = 4800;
802     }
803
804 /*
805  *  Further, source width must be a multiple of 32 (96 for RGB here).
806  */
807
808     RasterSize = ((RasterSize + 95) / 96) * 96;
809
810     m_pCompressor = new ModeJPEG (pSS, this, RasterSize, m_eCompressMode);
811     return m_pCompressor;
812 }
813
814 /*
815  *  Function name: ParseError
816  *
817  *  Owner: Darrell Walker
818  *
819  *  Purpose:  To determine what error state the printer is in.
820  *
821  *  Called by: Send()
822  *
823  *  Parameters on entry: status_reg is the contents of the centronics
824  *                      status register (at the time the error was
825  *                      detected)
826  *
827  *  Parameters on exit: unchanged
828  *
829  *  Return Values: The proper DISPLAY_STATUS to reflect the printer
830  *              error state.
831  *
832  */
833 DISPLAY_STATUS LJJetReady::ParseError(BYTE status_reg)
834 {
835     DBG1("LJJetReady: parsing error info\n");
836
837     DRIVER_ERROR err = NO_ERROR;
838     BYTE    szReadBuff[256];
839     DWORD   iReadCount = 256;
840     DISPLAY_STATUS  eStatus = (DISPLAY_STATUS) status_reg;
841     char    *tmpStr;
842     int     iErrorCode;
843
844     if (!IOMode.bDevID)
845         return eStatus;
846
847     memset (szReadBuff, 0, 256);
848     err = pSS->FromDevice (szReadBuff, &iReadCount);
849     if (err == NO_ERROR && iReadCount == 0)
850         return eStatus;
851
852     if (strstr ((char *) szReadBuff, "JOB"))
853     {
854         if (!(tmpStr = strstr ((char *) szReadBuff, "NAME")))
855             return DISPLAY_PRINTING;
856         tmpStr += 6;
857         while (*tmpStr < '0' || *tmpStr > '9')
858             tmpStr++;
859         sscanf (tmpStr, "%d", &iErrorCode);
860         if (iErrorCode != (long) (this))
861             return DISPLAY_PRINTING;
862     }
863
864     if (strstr ((char *) szReadBuff, "END"))
865     {
866         return DISPLAY_PRINTING_COMPLETE;
867     }
868
869
870     if (strstr ((char *) szReadBuff, "CANCEL"))
871         return DISPLAY_PRINTING_CANCELED;
872
873     if (!(tmpStr = strstr ((char *) szReadBuff, "CODE")))
874         return eStatus;
875
876     tmpStr += 4;
877     while (*tmpStr < '0' || *tmpStr > '9')
878         tmpStr++;
879     sscanf (tmpStr, "%d", &iErrorCode);
880
881     if (iErrorCode < 32000)
882         return DISPLAY_PRINTING;
883
884     if (iErrorCode == 40010 || iErrorCode == 40020)
885         return DISPLAY_NO_PENS;     // Actually, out of toner
886
887     if (iErrorCode == 40021)
888         return DISPLAY_TOP_COVER_OPEN;
889
890     if ((iErrorCode / 100) == 419)
891         return DISPLAY_OUT_OF_PAPER;
892
893     if ((iErrorCode / 1000) == 42 || iErrorCode == 40022)
894     {
895         DBG1("Paper Jammed\n");
896         return DISPLAY_PAPER_JAMMED;
897     }
898
899     if (iErrorCode > 40049 && iErrorCode < 41000)
900     {
901         DBG1("IO trap\n");
902         return DISPLAY_ERROR_TRAP;
903     }
904
905     if (iErrorCode == 40079)
906         return DISPLAY_OFFLINE;
907
908     return DISPLAY_ERROR_TRAP;
909 }
910
911 BYTE *    ModeJPEG::fpJPEGBuffer = NULL;       // image buffer
912 DWORD     ModeJPEG::fJPEGBufferPos;            // position of 1'st empty byte in image buffer
913
914 void ModeJPEG::jpeg_flush_output_buffer_callback(JOCTET *outbuf, BYTE* buffer, DWORD size)
915 {
916     fJPEGBufferPos += size;
917     memcpy (fpJPEGBuffer, buffer, size);
918     fpJPEGBuffer += size;
919 }
920
921 //----------------------------------------------------------------
922 // These are "overrides" to the JPEG library error routines
923 //----------------------------------------------------------------
924 static void Gjpeg_error (j_common_ptr cinfo)
925 {
926     // The standard behavior is to send a message to stderr.
927 }
928 /*
929 void ModeJPEG::SetBuffer(BYTE * pJPEGBuffer)
930 {
931     fpJPEGBuffer = pJPEGBuffer;
932 }
933 */
934 DWORD ModeJPEG::GetJPEGBufferSize() const
935 {
936     return fJPEGBufferPos;
937 }
938
939 /*
940 BYTE* ModeJPEG::GetBuffer() 
941 {
942     return fpJPEGBuffer;
943 }
944 */
945
946 extern "C"
947 {
948 void jpeg_buffer_dest (j_compress_ptr cinfo, JOCTET* outbuff, void* flush_output_buffer_callback);\r
949 void hp_rgb_ycc_setup (int iFlag);\r
950 }
951
952 #define ConvertToGrayMacro(red, green, blue) ((unsigned char)( ( (red * 30) + (green * 59) + (blue * 11) ) / 100 ))
953
954 //--------------------------------------------------------------------
955 // Function:    ModeJPEG::ModeJPEG
956 //
957 // Release:     [PROTO4_1]
958 //
959 // Description: Preferred ctor
960 //
961 // Input:        padMultiple - the fBufferDataLength returned from
962 //                             GetRow must be divisible by this value.
963 //
964 // Modifies:     fpBuffer
965 //
966 // Precond:      None
967 //
968 // Postcond:     None
969 //
970 // Returns:      None
971 //
972 // Created:            11/07/96 cal
973 // Last Modified:      5/020/01 DG
974 //--------------------------------------------------------------------
975 ModeJPEG::ModeJPEG 
976 (    
977         SystemServices* pSys,
978     Printer* pPrinter,
979     unsigned int PlaneSize,
980     COMPRESS_MODE eCompressMode
981 ) :
982     Compressor(pSys, PlaneSize, TRUE),
983     thePrinter(pPrinter)    // needed by Flush                        
984 {
985     if (constructor_error != NO_ERROR)  // if error in base constructor
986     {
987         return;
988     }
989     fpJPEGBuffer = NULL;    // image buffer
990     fJPEGBufferPos = 0;     // position of 1'st empty byte in image buffer
991     fpJPEGStart = NULL;
992
993         m_SourceBitmap.pvBits = (BYTE*) new BYTE[(inputsize * MOJAVE_STRIP_HEIGHT)];
994
995         if (m_SourceBitmap.pvBits == NULL)
996     {
997                 constructor_error = ALLOCMEM_ERROR;
998     }
999     else
1000     {
1001         memset (m_SourceBitmap.pvBits, 0xFF, inputsize * MOJAVE_STRIP_HEIGHT);
1002     }
1003     m_SourceBitmap.cjBits = 0;
1004     m_SourceBitmap.bitmapInfo.bmiHeader.biWidth = 0;
1005     m_SourceBitmap.bitmapInfo.bmiHeader.biHeight = 0;
1006
1007
1008         m_DestBitmap.pvBits = NULL;
1009     m_DestBitmap.cjBits = 0;
1010     m_DestBitmap.bitmapInfo.bmiHeader.biWidth = 0;
1011     m_DestBitmap.bitmapInfo.bmiHeader.biHeight = 0;
1012
1013         m_lCurrCDRasterRow      = 0;
1014         m_lPrinterRasterRow = 0;
1015
1016     m_iRasterWidth = inputsize / 3;
1017
1018         iRastersReady = 0;
1019
1020         compressBuf = NULL;
1021     m_eCompressMode = eCompressMode;
1022
1023 } // ModeJPEG::ModeJPEG
1024
1025
1026 //--------------------------------------------------------------------
1027 // Function:    ModeJPEG::~ModeJPEG
1028 //
1029 // Release:     [PROTO4_1]
1030 //
1031 // Description: Destructor.
1032 //
1033 // Input:       None
1034 //
1035 // Modifies:    fpBuffer - deletes the buffer
1036 //              ?? - deletes other buffer(s)??
1037 //
1038 // Precond:     None
1039 //
1040 // Postcond:    None
1041 //
1042 // Returns:     None
1043 //
1044 // Created:            11/07/96 cal
1045 // Last Modified:      5/020/01 DG
1046 //--------------------------------------------------------------------
1047 ModeJPEG::~ModeJPEG ()
1048 {   
1049         if (m_SourceBitmap.pvBits)
1050         {
1051                 delete m_SourceBitmap.pvBits;
1052                 m_SourceBitmap.pvBits = NULL;
1053         }
1054
1055         if (m_DestBitmap.pvBits)
1056         {
1057                 delete m_DestBitmap.pvBits;
1058                 m_DestBitmap.pvBits = NULL;
1059         }
1060
1061 } // ModeJPEG::~ModeJPEG
1062
1063 /*
1064  *  JetReady specs require that data be sent for the whole page. When input data
1065  *  does not cover the whole page, send white rasters to cover the rest of the
1066  *  page.
1067  */
1068
1069 DRIVER_ERROR ModeJPEG::SendWhiteStrips (int iPageHeight, BOOL bGray)
1070 {
1071     DRIVER_ERROR    err = NO_ERROR;
1072         HPLJBITMAP      hWhiteBitmap;
1073     QTABLEINFO      qTableInfo;
1074     RASTERDATA      whiteRaster;
1075
1076     qTableInfo.qFactor = 6;
1077
1078         hWhiteBitmap.pvBits = NULL;
1079
1080         if (bGray)
1081         {
1082         m_SourceBitmap.cjBits = m_iRasterWidth * MOJAVE_STRIP_HEIGHT;
1083         memset (m_SourceBitmap.pvBits, 0x00, m_SourceBitmap.cjBits);
1084     }
1085     else
1086     {
1087         m_SourceBitmap.cjBits = m_iRasterWidth * MOJAVE_STRIP_HEIGHT * 3;
1088         memset (m_SourceBitmap.pvBits, 0xFF, m_SourceBitmap.cjBits);
1089     }
1090         memset(&m_SourceBitmap.bitmapInfo.bmiHeader, 0, sizeof(HPBITMAPINFOHEADER));
1091         m_SourceBitmap.bitmapInfo.bmiHeader.biWidth = m_iRasterWidth;
1092         m_SourceBitmap.bitmapInfo.bmiHeader.biHeight = MOJAVE_STRIP_HEIGHT;
1093         m_SourceBitmap.bitmapInfo.bmiHeader.biSizeImage = m_SourceBitmap.cjBits;
1094         m_SourceBitmap.bitmapInfo.bmiHeader.biBitCount = 8;
1095     Compress (&m_SourceBitmap, &m_DestBitmap, &qTableInfo, bGray);
1096     whiteRaster.rastersize[COLORTYPE_COLOR] = m_DestBitmap.cjBits;
1097     whiteRaster.rasterdata[COLORTYPE_COLOR] = m_DestBitmap.pvBits;
1098     while (m_lPrinterRasterRow < iPageHeight)
1099     {
1100         thePrinter->Encapsulate (&whiteRaster, TRUE);
1101         m_lPrinterRasterRow += MOJAVE_STRIP_HEIGHT;
1102     }
1103
1104     return err;
1105 }
1106
1107 BOOL  ModeJPEG::Compress( HPLJBITMAP *pSrcBitmap,
1108                           HPLJBITMAP *pTrgBitmap,
1109                           QTABLEINFO *pQTable,
1110                                                   BOOL            bGrayscaleSet
1111                         ) 
1112
1113 {
1114 #ifdef HAVE_LIBDL
1115     if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
1116     {
1117         int     iRet;
1118         memcpy (pTrgBitmap, pSrcBitmap, sizeof (HPLJBITMAP));
1119         pTrgBitmap->pvBits = new BYTE[pSrcBitmap->bitmapInfo.bmiHeader.biWidth * pSrcBitmap->bitmapInfo.bmiHeader.biHeight * 3];
1120         if (pTrgBitmap->pvBits == NULL)
1121         {
1122             return FALSE;
1123         }\r
1124         if (bGrayscaleSet)\r
1125         {\r
1126             BYTE    *p = pSrcBitmap->pvBits;\r
1127             for (int j = 0; j < pSrcBitmap->bitmapInfo.bmiHeader.biHeight; j++)\r
1128             {\r
1129                 for (int i = 0; i < pSrcBitmap->bitmapInfo.bmiHeader.biWidth; i++)\r
1130                 {\r
1131                     p[0] = ConvertToGrayMacro (p[0], p[1], p[2]);\r
1132                     p[1] = p[2] = 0;\r
1133                     p += 3;\r
1134                 }\r
1135             }\r
1136         }
1137         iRet = HPLJJRCompress (pTrgBitmap->pvBits, (uint32_t *) &pTrgBitmap->cjBits, pSrcBitmap->pvBits,
1138                                pSrcBitmap->bitmapInfo.bmiHeader.biWidth, pSrcBitmap->bitmapInfo.bmiHeader.biHeight);
1139         if (iRet < 0)
1140             return FALSE;
1141         return TRUE;
1142     }
1143 #endif // HAVE_LIBDL
1144
1145 #ifdef JPEG_FILE_OUTPUT
1146         static int ifilecount = 0;
1147     char szFileName [256];
1148     sprintf(szFileName,"C:\\Temp\\compressed%03d",ifilecount++);
1149     strcat(szFileName,".jpg");
1150     FILE *pFile = fopen(szFileName, "w+b");
1151 #endif
1152
1153         fJPEGBufferPos = 0;
1154 \r
1155     hp_rgb_ycc_setup (1);   // Use modified Mojave CSC table\r
1156
1157     //----------------------------------------------------------------
1158     // Setup for compression 
1159     //----------------------------------------------------------------
1160     
1161     //----------------------------------------------------------------
1162     // JPEG Lib Step 1: Allocate and initialize JPEG compression object
1163     //----------------------------------------------------------------
1164     cinfo.err = jpeg_std_error( &jerr );
1165
1166     //Fix the error handler to return when an error occurs,
1167     //the default exit()s which is nasty for a driver to do.
1168     jerr.error_exit = Gjpeg_error;
1169     //Set the return jump address. This must be done now since
1170     // jpeg_create_compress could cause an error.
1171     if (setjmp(setjmp_buffer)) {
1172
1173         // If we get here, the JPEG code has signaled an error.
1174         //* We need to clean up the JPEG object, and return.
1175          
1176         jpeg_destroy_compress(&cinfo);
1177         return FALSE;
1178     }\r
1179 \r
1180     jpeg_create_compress( &cinfo );
1181    
1182     //----------------------------------------------------------------
1183     // JPEG Lib Step 2: Specify the destination for the compressed data
1184     // For our purposes we need to replace the "data destination" module
1185     // with one that uses the JPEG library's I/O suspension mode.
1186     // The buffer pointer and free space are updated each time GetNextRow
1187     // is called; so only the function pointers are set here.
1188     //----------------------------------------------------------------
1189
1190     //----------------------------------------------------------------
1191     // JPEG Lib Step 3: Set parameters for compression, including image size & colorspace
1192     //----------------------------------------------------------------
1193 \r
1194     int iColorsUsed;\r
1195
1196     if(bGrayscaleSet)
1197     {\r
1198         cinfo.in_color_space = JCS_GRAYSCALE;\r
1199         iColorsUsed = 1;
1200     }
1201     else
1202     {
1203         cinfo.in_color_space = JCS_RGB; // arbitrary guess\r
1204         iColorsUsed = 3;\r
1205     }
1206     jpeg_set_defaults( &cinfo );
1207
1208     cinfo.image_width = pSrcBitmap->bitmapInfo.bmiHeader.biWidth; 
1209     cinfo.image_height = pSrcBitmap->bitmapInfo.bmiHeader.biHeight;
1210     cinfo.input_components = iColorsUsed;  //change if bit depths others than 24bpp are ever needed
1211     cinfo.data_precision = 8;
1212
1213     //
1214     // Create a static quant table here. 
1215     //
1216     static unsigned int mojave_quant_table1[64] =  { 2,3,4,5,5,5,5,5,
1217                                                     3,6,5,8,5,8,5,8,
1218                                                     4,5,5,5,5,5,5,5,
1219                                                     5,8,5,8,5,8,5,8,
1220                                                     5,5,5,5,5,5,5,5,
1221                                                     5,8,5,8,5,8,5,8,
1222                                                     5,5,5,5,5,5,5,5,
1223                                                     5,8,5,8,5,8,5,8 };
1224     //
1225     // Use this variable for representing the scale_factor for now.
1226     //
1227     unsigned int iScaleFactor = pQTable->qFactor;
1228     
1229     //
1230     // JetReady specific Q-Tables will be added here. We do the following:
1231     //  1. Add three Q-Tables.
1232     //  2. Scale the Q-Table elemets with the given scale factor.
1233     //  3. Check to see if any of the element is in the table is greater than 255
1234     //     reset that elemet to 255.
1235     //  5. There is a specific scaling need to be done to the first 6 
1236     //     elements in the matrix. This required to achieve the better
1237     //     compression ratio.
1238     //  4. Check to see if any the of recently modified element is
1239     //     greater than 255, reset that with 255.
1240     //  Following for loop implements the above logic.
1241     //
1242     //  Please refer to sRGBLaserHostBasedSoftwareERS.doc v9.0 section 5.2.5.3.1.1
1243     //  for more details.
1244     //
1245     //  [NOTE] These loop needs to be further optimized.
1246     //
1247     for (int i = 0; i < 3; i++)
1248     {
1249         //
1250         // Adding Q-Table.
1251         //
1252         jpeg_add_quant_table(&cinfo, i, mojave_quant_table1,  0, FALSE );
1253         //
1254         // Scaling the Q-Table elements. 
1255         // Reset the element to 255, if it is greater than 255.
1256         //
1257         for(int j = 1; j < 64; j++)
1258         {
1259             cinfo.quant_tbl_ptrs[i]->quantval[j] = (UINT16)((mojave_quant_table1[j] * iScaleFactor) & 0xFF);  
1260
1261         }   // for (int j = 1; j < 64; j++)
1262         //
1263         // Special scaling for first 6 elements in the table.
1264         // Reset the specially scaled elements 255, if it is greater than 255.
1265         //
1266
1267         //
1268         // 1st component in the table. Unchanged, I need not change anything here.
1269         //
1270         cinfo.quant_tbl_ptrs[i]->quantval[0] = (UINT16)mojave_quant_table1[0];
1271         
1272         //
1273         // 2nd and 3rd components in the zig zag order
1274         //
1275                 // The following dTemp is being used  to ceil the vales: e.g 28.5 to 29
1276         //
1277         double dTemp = mojave_quant_table1[1] * (1 + 0.25 * (iScaleFactor - 1)) + 0.5;
1278         cinfo.quant_tbl_ptrs[i]->quantval[1] = (UINT16)dTemp & 0xFF;
1279         
1280         dTemp = mojave_quant_table1[8] * (1 + 0.25 * (iScaleFactor - 1)) + 0.5;
1281         cinfo.quant_tbl_ptrs[i]->quantval[8] = (UINT16)dTemp & 0xFF;
1282        
1283         //
1284         // 4th, 5th and 6th components in the zig zag order
1285         //
1286         dTemp = mojave_quant_table1[16] * (1 + 0.50 * (iScaleFactor - 1)) + 0.5;
1287         cinfo.quant_tbl_ptrs[i]->quantval[16] = (UINT16)dTemp & 0xFF;
1288         
1289         dTemp = mojave_quant_table1[9] * (1 + 0.50 * (iScaleFactor - 1)) + 0.5;
1290         cinfo.quant_tbl_ptrs[i]->quantval[9]  = (UINT16)dTemp & 0xFF;
1291         
1292         dTemp = mojave_quant_table1[2] * (1 + 0.50 * (iScaleFactor - 1)) + 0.5;
1293         cinfo.quant_tbl_ptrs[i]->quantval[2]  = (UINT16)dTemp & 0xFF;
1294     }   // for (i = 0; i < 3; i++)
1295
1296     //
1297     // Hard code to use sampling mode 4:4:4
1298     //
1299     cinfo.comp_info[0].h_samp_factor = 1;
1300     cinfo.comp_info[0].v_samp_factor = 1;
1301
1302     // Specify data destination for compression 
1303     fpJPEGBuffer = new BYTE[cinfo.image_width * cinfo.image_height * iColorsUsed];  //3 bytes for 24 bpp
1304     if (NULL == fpJPEGBuffer)
1305     {
1306         //ERR(("JPEGCompress: Not enough memory\n"));
1307         return FALSE;
1308     }
1309
1310     fpJPEGStart = fpJPEGBuffer;
1311
1312     jpeg_buffer_dest(&cinfo, (JOCTET *) fpJPEGBuffer, (void*) (ModeJPEG::jpeg_flush_output_buffer_callback));
1313     if(bGrayscaleSet)
1314     {
1315         cinfo.write_JFIF_header  =
1316         cinfo.write_Adobe_marker = FALSE;
1317         jpeg_suppress_tables(&cinfo, TRUE);
1318     }
1319
1320     //----------------------------------------------------------------
1321     // JPEG Lib Step 4: Start the compression cycle
1322     //  set destination to table file
1323     //    jpeg_write_tables(cinfo);
1324     //    set destination to image file
1325     //  jpeg_start_compress(cinfo, FALSE);
1326     //----------------------------------------------------------------
1327     
1328     jpeg_start_compress( &cinfo, TRUE );    
1329    
1330
1331     //----------------------------------------------------------------
1332     // This completes the JPEG setup.
1333     //----------------------------------------------------------------
1334     
1335
1336     // do the jpeg compression
1337     JSAMPROW    pRowArray[1];
1338     BYTE* pCurLine = (BYTE*) pSrcBitmap->pvBits;
1339     DWORD dwScanLine;
1340     
1341     dwScanLine = cinfo.image_width * iColorsUsed;
1342
1343         for(unsigned int nrow = 0; nrow < cinfo.image_height; nrow++)
1344     {
1345         pRowArray[0] = (JSAMPROW) pCurLine;
1346         jpeg_write_scanlines(&cinfo, pRowArray, 1);
1347         pCurLine += dwScanLine;
1348     }
1349
1350     //----------------------------------------------------------------
1351     // JPEG Lib Step 6: Finish compression
1352     //----------------------------------------------------------------
1353     // Tell the compressor about the extra buffer space for the trailer
1354     jpeg_finish_compress( &cinfo );
1355
1356     //
1357     // Read the quantization tables used for the compression.
1358     //
1359
1360     if (cinfo.quant_tbl_ptrs[0] != NULL)
1361     {
1362         for (int iI = 0; iI < QTABLE_SIZE; iI++)
1363         {
1364             pQTable->qtable0[iI] = (DWORD)cinfo.quant_tbl_ptrs[0]->quantval[iI];
1365         }
1366
1367     }
1368
1369     if (cinfo.quant_tbl_ptrs[1] != NULL)
1370     {
1371         for (int iI = 0; iI < QTABLE_SIZE; iI++)
1372         {
1373             pQTable->qtable1[iI] = (DWORD)cinfo.quant_tbl_ptrs[1]->quantval[iI];
1374         }
1375     }
1376
1377     if (cinfo.quant_tbl_ptrs[2] != NULL)
1378     {
1379         for (int iI = 0; iI < QTABLE_SIZE; iI++)
1380         {
1381             pQTable->qtable2[iI] = (DWORD)cinfo.quant_tbl_ptrs[2]->quantval[iI];
1382         }
1383     }
1384
1385
1386     //----------------------------------------------------------------
1387     // JPEG Lib Step 7: Destroy the compression object
1388     //----------------------------------------------------------------
1389     jpeg_destroy_compress( &cinfo );
1390                   
1391     memcpy(pTrgBitmap, pSrcBitmap, sizeof(HPLJBITMAP));
1392
1393 #ifdef JPEG_FILE_OUTPUT
1394         fwrite(fpJPEGStart, sizeof(BYTE), GetJPEGBufferSize(), pFile);
1395 #endif
1396     //
1397     if(fpJPEGStart && bGrayscaleSet)
1398     {
1399         long lBufferSize = GetJPEGBufferSize();
1400         long l = 0;
1401         while (l < lBufferSize)
1402         {
1403             if(fpJPEGStart[l] == 0xFF && fpJPEGStart[l+1] == 0xDA)
1404                 break;
1405             l++;
1406         }
1407         if(l != lBufferSize)
1408         {
1409             memcpy (fpJPEGStart, fpJPEGStart + l + 10, lBufferSize - l - 10);
1410             memset (fpJPEGStart + lBufferSize - l - 10, 0xFF, l + 10);
1411             pTrgBitmap->cjBits = lBufferSize - l - 10;
1412             pTrgBitmap->pvBits = (BYTE*)fpJPEGStart;
1413         }
1414         else
1415         {
1416             pTrgBitmap->pvBits = (BYTE*)fpJPEGStart;
1417         }
1418     }
1419     else
1420     {
1421         pTrgBitmap->pvBits = (BYTE*) fpJPEGStart;
1422         pTrgBitmap->cjBits = GetJPEGBufferSize();
1423     }
1424
1425 #ifdef JPEG_FILE_OUTPUT
1426         fclose(pFile);
1427 #endif
1428
1429     return TRUE;
1430
1431 }
1432
1433 BOOL ModeJPEG::Process
1434 (
1435     RASTERDATA* input
1436 )
1437 {
1438         DRIVER_ERROR            err = NO_ERROR;
1439
1440     if (input==NULL || 
1441                 (input->rasterdata[COLORTYPE_COLOR]==NULL && input->rasterdata[COLORTYPE_BLACK]==NULL))    // flushing pipeline
1442     {
1443         return FALSE;
1444     }
1445         if (input->rasterdata[COLORTYPE_COLOR])
1446         {
1447                 if (m_lCurrCDRasterRow < MOJAVE_STRIP_HEIGHT )
1448                 {
1449                         //Copy the data to m_SourceBitmap
1450                         memcpy(m_SourceBitmap.pvBits + m_lCurrCDRasterRow * inputsize, input->rasterdata[COLORTYPE_COLOR], input->rastersize[COLORTYPE_COLOR]);
1451                         m_lCurrCDRasterRow ++;
1452                 }
1453
1454                 if (m_lCurrCDRasterRow == MOJAVE_STRIP_HEIGHT || ((LJJetReady*)thePrinter)->phLJJetReady->IsLastBand())
1455                 {
1456                         m_SourceBitmap.cjBits = inputsize * MOJAVE_STRIP_HEIGHT;
1457                         memset(&m_SourceBitmap.bitmapInfo.bmiHeader, 0, sizeof(HPBITMAPINFOHEADER));
1458                         m_SourceBitmap.bitmapInfo.bmiHeader.biWidth = inputsize / 3;
1459                         m_SourceBitmap.bitmapInfo.bmiHeader.biHeight = MOJAVE_STRIP_HEIGHT;
1460
1461                         QTABLEINFO  qTableInfo;
1462                         BOOL    bGrayScaleSet = ((LJJetReady *)thePrinter)->bGrey_K;
1463                         BOOL    bRet              = TRUE;
1464
1465                         qTableInfo.qFactor = 6;
1466                         if (((LJJetReady*)thePrinter)->m_bStartPageNotSent)
1467                         {
1468                                 err = (((LJJetReady*)thePrinter)->phLJJetReady)->StartPage();
1469                                 ((LJJetReady*)thePrinter)->m_bStartPageNotSent = FALSE;
1470
1471                                 char res[64];
1472                                 //
1473                                 //  0xC2       - unsigned 32 bit int   
1474                                 //  0x68704000 - begin image for the JetReady path - endin correct to 00 40 70 68
1475                                 //  0xF8       - unsigned 8 bit attribute
1476                                 //  0x91       - VUextension  (a vendor unique attribute for JetReady) 
1477                                 //  0xC1       - Unsigned 16 bit int
1478                                 err = thePrinter->Send ((const BYTE *)JrBeginImageSeq, sizeof(JrBeginImageSeq));
1479                                 ERRCHECK;
1480
1481                                 unsigned short int sourcewidth = (unsigned short int) (inputsize / 3);
1482                                 unsigned short int sourceheight = (unsigned short int)((((LJJetReady*)thePrinter)->phLJJetReady)->thePrintContext->PhysicalPageSizeY() * MOJAVE_RESOLUTION - 200);
1483                                 if ( 0 != (sourceheight % MOJAVE_STRIP_HEIGHT) )
1484                                 {
1485                                         sourceheight = ( (sourceheight / MOJAVE_STRIP_HEIGHT) + 1) * MOJAVE_STRIP_HEIGHT;
1486                                 }       
1487
1488                                 //Write the source width to the printer;
1489 //                              err = thePrinter->Send ((const BYTE*)&sourcewidth, sizeof(unsigned short int));
1490                 res[0] = sourcewidth & 0x00FF;
1491                 res[1] = ((sourcewidth & 0xFF00) >> 8);
1492                 err = thePrinter->Send ((const BYTE *) res, 2);
1493                                 ERRCHECK;
1494                                 //  0xF8       - unsigned 8 bit attribute
1495                                 //  0x6C       - source width attribute
1496                                 //  0xC1       - Unsigned 16 bit int
1497                                 strcpy (res, "\xF8\x6C\xC1");
1498                                 err = thePrinter->Send ((const BYTE *) res, strlen (res));
1499                                 ERRCHECK;
1500                                 
1501                                 //Write the source height to the printer
1502 //                              err = thePrinter->Send ((const BYTE*)&sourceheight, sizeof(unsigned short int));
1503                 res[0] = sourceheight & 0x00FF;
1504                 res[1] = ((sourceheight & 0xFF00) >> 8);
1505                 err = thePrinter->Send ((const BYTE *) res, 2);
1506                                 ERRCHECK;
1507                                 // 0xF8       - unsigned 8 bit attribute
1508                                 // 0x6B       - source height attribute
1509                                 // 0xC1       - Unsigned 16 bit int
1510                                 strcpy (res, "\xF8\x6B\xC1");
1511                                 err = thePrinter->Send ((const BYTE *) res, strlen (res));
1512                                 ERRCHECK;
1513                                 
1514                                 unsigned short int stripcount = sourceheight / MOJAVE_STRIP_HEIGHT;
1515                                 //stripcount = 4;
1516 //                              err = thePrinter->Send ((const BYTE *)&stripcount, sizeof(stripcount));
1517                 res[0] = stripcount & 0x00FF;
1518                 res[1] = ((stripcount & 0xFF00) >> 8);
1519                 err = thePrinter->Send ((const BYTE *) res, 2);
1520                                 ERRCHECK;
1521                                 //0xF8       - unsigned 8 bit attribute
1522                                 //0x93       - special attribute 1 for strip count  
1523                                 //0xC1       - Unsigned 16 bit int
1524                                 strcpy (res, "\xF8\x93\xC1");
1525                                 err = thePrinter->Send ((const BYTE *) res, strlen (res));
1526                                 //BYTE JrStripCountSeq[] = {0x32,0x00,0xF8,0x93,0xC1};
1527                                 //err = thePrinter->Send ((const BYTE *)JrStripCountSeq, sizeof(JrStripCountSeq));
1528                                 ERRCHECK;
1529
1530                                 // Write the MOJAVE_STRIP_HEIGHT value
1531                                 //0xF8       - unsigned 8 bit attribute
1532                                 //0x94       - special attribute 2 used for strip height
1533                                 BYTE JrStripHeightSeq[] = {0x80,0x00,0xF8,0x94};
1534                                 err = thePrinter->Send ((const BYTE *)JrStripHeightSeq, sizeof(JrStripHeightSeq));
1535                                 ERRCHECK;
1536
1537                                 if  (bGrayScaleSet)
1538                                 {
1539                                         // 0x00 indicates grayscale printing
1540                                         BYTE JrGrayScaleSeq[] = {0xC0,0x00,0xF8,0x97};
1541                                         err = thePrinter->Send ((const BYTE *)JrGrayScaleSeq, sizeof(JrGrayScaleSeq));
1542                                         ERRCHECK;
1543                                 }
1544                                 else
1545                                 {
1546                                         // 0x04 indicates Color printing
1547                                         BYTE JrColorSeq[] = {0xC0,0x04,0xF8,0x97};
1548                                         err = thePrinter->Send ((const BYTE *)JrColorSeq, sizeof(JrColorSeq));
1549                                         ERRCHECK;
1550                                 }
1551
1552                                 // Interleaved Color Enumeration for Mojave
1553                                 BYTE JrSeq[] = {0xC0,0x00,0xF8,0x98};
1554                                 err = thePrinter->Send ((const BYTE *)JrSeq, sizeof(JrSeq));
1555                                 ERRCHECK;
1556
1557                                 //0xC2       - unsigned 32 bit int   
1558                                 //0x00030000 - JetReady version number 
1559                                 //0xF8       - unsigned 8 bit attribute
1560                                 //0x95       - JetReadyVersion attribute
1561                                 err = thePrinter->Send ((const BYTE *)JrVU_ver_TagSeq, sizeof(JrVU_ver_TagSeq));
1562                                 ERRCHECK;
1563
1564                                 //  Send the JPEG statement for the sake of Dual Compression
1565                                 //  0xC2       - unsigned 32 bit int   
1566                                 //  VU DataLength - 824 bytes for jpeg header
1567                                 //  0xF8       - unsigned 8 bit attribute
1568                                 //  0x92       - VU data length
1569                                 //  0x46       - vendor unique  
1570                                 BYTE JrDataLengthSeq[] = {0xC2,0x38,0x03,0x00,0x00,0xF8,0x92,0x46};
1571 #ifdef HAVE_LIBDL
1572                 if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
1573                 {
1574                     JrDataLengthSeq[1] = 0;
1575                     JrDataLengthSeq[2] = 0;
1576                 }
1577 #endif
1578                                 err = thePrinter->Send ((const BYTE *)JrDataLengthSeq, sizeof(JrDataLengthSeq));
1579                                 ERRCHECK;
1580
1581                                 bRet = Compress (&m_SourceBitmap, 
1582                                                                  &m_DestBitmap,
1583                                                                  &qTableInfo,
1584                                                                  FALSE  // We are only worried about the qTables not about the colorspace.
1585                                                             );
1586                 if (!HPLJJRCompress || (HPLJJRCompress && m_eCompressMode != COMPRESS_MODE_LJ))
1587                 {
1588
1589                                     //VWritePrinter("\x00\x80\x00\x03\x00\x00", 0x6);
1590                                     BYTE JrQTSeq[] = {0x00,0x80,0x00,0x03,0x00,0x00};
1591                                     err = thePrinter->Send ((const BYTE *)JrQTSeq, sizeof(JrQTSeq));
1592                                     ERRCHECK;
1593
1594 #ifdef APDK_LITTLE_ENDIAN
1595                                     //VWritePrinter((VOID*) pQTableInfo->qtable0, sizeof(DWORD) * QTABLE_SIZE);
1596                                     err = thePrinter->Send ((const BYTE *)qTableInfo.qtable0, sizeof(DWORD) * QTABLE_SIZE);
1597                                     ERRCHECK;
1598
1599
1600                                     //VWritePrinter((VOID*) pQTableInfo->qtable1, sizeof(DWORD) * QTABLE_SIZE);
1601                                     err = thePrinter->Send ((const BYTE *)qTableInfo.qtable1, sizeof(DWORD) * QTABLE_SIZE);
1602                                     ERRCHECK;
1603
1604                                     //VWritePrinter((VOID*) pQTableInfo->qtable2, sizeof(DWORD) * QTABLE_SIZE);
1605                                     err = thePrinter->Send ((const BYTE *)qTableInfo.qtable2, sizeof(DWORD) * QTABLE_SIZE);
1606                                     ERRCHECK;
1607 #else
1608                     BYTE    szStr[sizeof (DWORD) * QTABLE_SIZE * 3];
1609                     BYTE    *p;
1610                     p = szStr;
1611                     for (int i = 0; i < QTABLE_SIZE; i++)
1612                     {
1613                         *p++ = qTableInfo.qtable0[i] & 0xFF;
1614                         *p++ = (qTableInfo.qtable0[i] >> 8) & 0xFF;
1615                         *p++ = (qTableInfo.qtable0[i] >> 16) & 0xFF;
1616                         *p++ = (qTableInfo.qtable0[i] >> 24) & 0xFF;
1617                     }
1618                     for (int i = 0; i < QTABLE_SIZE; i++)
1619                     {
1620                         *p++ = qTableInfo.qtable1[i] & 0xFF;
1621                         *p++ = (qTableInfo.qtable1[i] >> 8) & 0xFF;
1622                         *p++ = (qTableInfo.qtable1[i] >> 16) & 0xFF;
1623                         *p++ = (qTableInfo.qtable1[i] >> 24) & 0xFF;
1624                     }
1625                     for (int i = 0; i < QTABLE_SIZE; i++)
1626                     {
1627                         *p++ = qTableInfo.qtable2[i] & 0xFF;
1628                         *p++ = (qTableInfo.qtable2[i] >> 8) & 0xFF;
1629                         *p++ = (qTableInfo.qtable2[i] >> 16) & 0xFF;
1630                         *p++ = (qTableInfo.qtable2[i] >> 24) & 0xFF;
1631                     }
1632                     err = thePrinter->Send ((const BYTE *) szStr, 3 * sizeof (DWORD) * QTABLE_SIZE);
1633                     ERRCHECK;
1634
1635 #endif
1636                                     // Start of JPEG Control
1637                                     // 0x8001 JPEG Control register
1638                                     // size - unsigned 32 bit number 0x0000_002C
1639                                     // 11 32 bit words total = 44 bytes
1640                                     // Control  one
1641                                     // Color 0x6614_E001
1642                                     // Mono  0x0000_E005
1643                                     //
1644                                     //VWritePrinter("\x01\x80\x2C\x00\x00\x00", 0x6);
1645                                     BYTE JrCRSeq[] = {0x01,0x80,0x2C,0x00,0x00,0x00};
1646                                     err = thePrinter->Send ((const BYTE *)JrCRSeq, sizeof(JrCRSeq));
1647                                     ERRCHECK;
1648
1649                                     if (bGrayScaleSet)
1650                                     {
1651                                             //VWritePrinter("\x05\xE0\x00\x00", 0x4);
1652                                             BYTE JrCR1GSeq[] = {0x05,0xE0,0x00,0x00};
1653                                             err = thePrinter->Send ((const BYTE *)JrCR1GSeq, sizeof(JrCR1GSeq));
1654                                             ERRCHECK;
1655                                     }
1656                                     else
1657                                     {
1658                                             //VWritePrinter("\x01\xE0\x14\x66", 0x4);
1659                                             BYTE JrCR1CSeq[] = {0x01,0xE0,0x14,0x66};
1660                                             err = thePrinter->Send ((const BYTE *)JrCR1CSeq, sizeof(JrCR1CSeq));
1661                                             ERRCHECK;
1662                                     }
1663         
1664                                     //
1665                                     // Control three
1666                                     // Color 0x0000_0001
1667                                     // Mono  0x0000_0000
1668                                     // bit 0 = convert rgb data
1669                                     // bit 1: 0 = 13 bit precision 
1670                                     //        1 = 14 bit precision
1671                                     //
1672                                     if (bGrayScaleSet)
1673                                     {
1674                                             //VWritePrinter("\x00\x00\x00\x00", 0x4);
1675                                             BYTE JrCR3GSeq[] = {0x00,0x00,0x00,0x00};
1676
1677                                             err = thePrinter->Send ((const BYTE *)JrCR3GSeq, sizeof(JrCR3GSeq));
1678                                             ERRCHECK;
1679                                     }
1680                                     else
1681                                     {
1682                                             //VWritePrinter("\x01\x00\x00\x00", 0x4);
1683                                             BYTE JrCR3CSeq[] = {0x01,0x00,0x00,0x00};
1684                                             err = thePrinter->Send ((const BYTE *)JrCR3CSeq, sizeof(JrCR3CSeq));
1685                                             ERRCHECK;
1686                                     }
1687         
1688                                     //
1689                                     // CSC matrix
1690                                     // 11  12  13  2.0   0.0    0.0
1691                                     // 21  22  23  2.0  -2.0    0.0
1692                                     // 31  32  33  2.0   0.0   -2.0
1693
1694                                     // Decompression matrix
1695                                     //VWritePrinter("\x00\x20\x00\x00", 0x4);
1696                                     BYTE JrCSC1Seq[] = {0x00,0x20,0x00,0x00};
1697                                     err = thePrinter->Send ((const BYTE *)JrCSC1Seq, sizeof(JrCSC1Seq));
1698                                     ERRCHECK;
1699
1700                                     //VWritePrinter("\x00\x00\x00\x00", 0x4);
1701                                     BYTE JrCSC2Seq[] = {0x00,0x00,0x00,0x00};
1702                                     err = thePrinter->Send ((const BYTE *)JrCSC2Seq, sizeof(JrCSC2Seq));
1703                                     ERRCHECK;
1704
1705                                     //VWritePrinter("\x00\x00\x00\x00", 0x4);
1706                                     BYTE JrCSC3Seq[] = {0x00,0x00,0x00,0x00};
1707                                     err = thePrinter->Send ((const BYTE *)JrCSC3Seq, sizeof(JrCSC3Seq));
1708                                     ERRCHECK;
1709
1710                                     //VWritePrinter("\x00\x20\x00\x00", 0x4);
1711                                     BYTE JrCSC4Seq[] = {0x00,0x20,0x00,0x00};
1712                                     err = thePrinter->Send ((const BYTE *)JrCSC4Seq, sizeof(JrCSC4Seq));
1713                                     ERRCHECK;
1714
1715                                     //VWritePrinter("\x00\xE0\x00\x00", 0x4);
1716                                     BYTE JrCSC5Seq[] = {0x00,0xE0,0x00,0x00};
1717                                     err = thePrinter->Send ((const BYTE *)JrCSC5Seq, sizeof(JrCSC5Seq));
1718                                     ERRCHECK;
1719
1720                                     //VWritePrinter("\x00\x00\x00\x00", 0x4);
1721                                     BYTE JrCSC6Seq[] = {0x00,0x00,0x00,0x00};
1722                                     err = thePrinter->Send ((const BYTE *)JrCSC6Seq, sizeof(JrCSC6Seq));
1723                                     ERRCHECK;
1724
1725                                     //VWritePrinter("\x00\x20\x00\x00", 0x4);
1726                                     BYTE JrCSC7Seq[] = {0x00,0x20,0x00,0x00};
1727                                     err = thePrinter->Send ((const BYTE *)JrCSC7Seq, sizeof(JrCSC7Seq));
1728                                     ERRCHECK;
1729
1730                                     //VWritePrinter("\x00\x00\x00\x00", 0x4);
1731                                     BYTE JrCSC8Seq[] = {0x00,0x00,0x00,0x00};
1732                                     err = thePrinter->Send ((const BYTE *)JrCSC8Seq, sizeof(JrCSC8Seq));
1733                                     ERRCHECK;
1734
1735                                     //VWritePrinter("\x00\xE0\x00\x00", 0x4);
1736                                     BYTE JrCSC9Seq[] = {0x00,0xE0,0x00,0x00};
1737                                     err = thePrinter->Send ((const BYTE *)JrCSC9Seq, sizeof(JrCSC9Seq));
1738                                     ERRCHECK;
1739                 } // if (!HPLJJRCompress)
1740             }     // if (....bStartPageNotSent)
1741
1742
1743                         BYTE         *pbTemp;
1744                         HPLJBITMAP   jpegGrayBitmap;
1745
1746                         jpegGrayBitmap.pvBits = NULL;
1747                         //
1748                         // Convert 24bpp Gray to 8bpp Gray.
1749                         // JPEG takes K 8bpp gray data. We are using two different buffers for these.
1750                         //
1751                         if(bGrayScaleSet && m_eCompressMode == COMPRESS_MODE_JPEG)
1752                         {
1753                                 pbTemp = (BYTE*)m_SourceBitmap.pvBits;
1754         
1755                                 jpegGrayBitmap.pvBits = new BYTE[m_SourceBitmap.cjBits / 3];
1756
1757                                 for(long i = 0, j=0; i < (long)m_SourceBitmap.cjBits; i += 3, j++)
1758                                 {
1759                                         pbTemp[i] = ConvertToGrayMacro(pbTemp[i], pbTemp[i + 1], pbTemp[i + 2] );
1760                                         pbTemp[i]         = 255 - pbTemp[i];
1761                                         pbTemp[i + 1] = pbTemp[i];
1762                                         pbTemp[i + 2] = pbTemp[i];
1763
1764                                         jpegGrayBitmap.pvBits[j] = pbTemp[i];
1765                                 }
1766                         }
1767
1768                         if (m_DestBitmap.pvBits)
1769             {
1770                                 delete m_DestBitmap.pvBits;
1771                                 m_DestBitmap.pvBits = NULL;
1772                         }
1773                         //
1774                         // JPEG grayscale specific operations are done here.
1775                         //
1776                         if(bGrayScaleSet && m_eCompressMode == COMPRESS_MODE_JPEG)
1777                         {
1778                                 jpegGrayBitmap.cjBits = m_SourceBitmap.cjBits / 3;
1779                                 jpegGrayBitmap.bitmapInfo.bmiHeader.biSizeImage = m_SourceBitmap.bitmapInfo.bmiHeader.biSizeImage / 3;
1780                                 jpegGrayBitmap.bitmapInfo.bmiHeader.biBitCount = 8;
1781                                 jpegGrayBitmap.bitmapInfo.bmiHeader.biWidth = m_SourceBitmap.bitmapInfo.bmiHeader.biWidth;
1782                                 jpegGrayBitmap.bitmapInfo.bmiHeader.biHeight = m_SourceBitmap.bitmapInfo.bmiHeader.biHeight;
1783                         }
1784                         if (bGrayScaleSet && m_eCompressMode == COMPRESS_MODE_JPEG)
1785                         {
1786                                 bRet = Compress (&jpegGrayBitmap, &m_DestBitmap, &qTableInfo,bGrayScaleSet);
1787                         }
1788                         else
1789                         {
1790                                 bRet = Compress (&m_SourceBitmap, &m_DestBitmap, &qTableInfo,bGrayScaleSet);
1791                         }
1792
1793                         m_SourceBitmap.cjBits = 0;
1794                         m_SourceBitmap.bitmapInfo.bmiHeader.biWidth = 0;
1795                         m_SourceBitmap.bitmapInfo.bmiHeader.biHeight = 0;
1796
1797                         memset(m_SourceBitmap.pvBits, 0xFF, inputsize * MOJAVE_STRIP_HEIGHT);
1798
1799                         if (jpegGrayBitmap.pvBits)
1800                         {
1801                                 delete jpegGrayBitmap.pvBits;
1802                                 jpegGrayBitmap.pvBits = NULL;
1803                         }
1804                         m_lPrinterRasterRow += MOJAVE_STRIP_HEIGHT;
1805         
1806                         m_lCurrCDRasterRow = 0;
1807                         iRastersReady = 1;
1808
1809                         ((LJJetReady*)thePrinter)->phLJJetReady->SetLastBand(FALSE);
1810                 }
1811                 else
1812                 {
1813                         return FALSE;
1814                 }
1815         }
1816
1817         return TRUE;
1818 } //Process
1819
1820 BYTE* ModeJPEG::NextOutputRaster(COLORTYPE color)
1821 // since we return 1-for-1, just return result first call
1822 {
1823         if (iRastersReady==0)
1824                 return (BYTE*)NULL;
1825
1826         if (color == COLORTYPE_BLACK)
1827         {
1828                 return (BYTE*)NULL;
1829         }
1830         else
1831         {
1832                 iRastersReady=0;
1833                 return m_DestBitmap.pvBits;
1834         }
1835 }
1836
1837 unsigned int ModeJPEG::GetOutputWidth(COLORTYPE  color)
1838 {
1839         if (color == COLORTYPE_COLOR)
1840         {
1841                 return m_DestBitmap.cjBits;
1842         }
1843         else
1844         {
1845                 return 0;
1846         }
1847 } //GetOutputWidth
1848
1849 APDK_END_NAMESPACE
1850
1851 #endif  // defined APDK_LJJetReady