1 /*****************************************************************************\
2 ljjetready.cpp : Implimentation for the LJJetReady class
4 Copyright (c) 1996 - 2008, Hewlett-Packard Co.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
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.
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 \*****************************************************************************/
32 #ifdef APDK_LJJETREADY
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
39 //#define HAVE_PROTOTYPES
43 #include "ljjetready.h"
44 #include "printerproxy.h"
45 #include "resources.h"
53 int (*HPLJJRCompress) (BYTE *pbOutBuffer,
56 const uint32_t iLogicalImageWidth,
57 const uint32_t iLogicalImageHeight);
63 extern void *LoadPlugin (const char *szPluginName);
66 extern MediaSize PaperToMediaSize(PAPER_SIZE psize);
68 #define MOJAVE_STRIP_HEIGHT 128 // Mojave strip height should always be 128 for compression sake
70 #define MOJAVE_RESOLUTION 600 // Mojave supports only one resolution- 600 DPI
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};
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 };
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..
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
111 LJJetReady::LJJetReady (SystemServices* pSS, int numfonts, BOOL proto)
112 : Printer(pSS, numfonts, proto)
115 if ((!proto) && (IOMode.bDevID))
117 constructor_error = VerifyPenInfo();
120 else ePen = BOTH_PENS; // matches default mode
122 pMode[GRAYMODE_INDEX] = new LJJetReadyGrayMode ();
123 pMode[DEFAULTMODE_INDEX] = new LJJetReadyNormalMode ();
128 m_bJobStarted = FALSE;
129 #ifdef APDK_AUTODUPLEX
130 m_bRotateBackPage = FALSE; // Lasers don't require back side image to be rotated
132 m_pCompressor = NULL;
135 m_bStartPageNotSent = TRUE;
137 HPLJJRCompress = NULL;
140 m_hHPLibHandle = LoadPlugin ("lj.so");
144 *(void **) (&HPLJJRCompress) = dlsym (m_hHPLibHandle, "HPJetReadyCompress");
148 pMode[ModeCount] = new LJJetReadyBestColorMode ();
150 pMode[ModeCount] = new LJJetReadyBestGrayMode ();
154 m_eCompressMode = COMPRESS_MODE_JPEG;
156 DBG1("LJJetReady created\n");
159 LJJetReady::~LJJetReady ()
161 DISPLAY_STATUS eDispStatus;
166 dlclose (m_hHPLibHandle);
170 if (IOMode.bStatus && m_bJobStarted)
172 for (int i = 0; i < 5; i++)
174 pSS->BusyWait (2000);
175 eDispStatus = ParseError (0);
176 if (eDispStatus == DISPLAY_PRINTING_COMPLETE)
178 pSS->DisplayPrinterStatus (eDispStatus);
185 LJJetReadyNormalMode::LJJetReadyNormalMode ()
188 ResolutionX[0] = 600;
189 ResolutionY[0] = 600;
190 BaseResX = BaseResY = 600;
192 bFontCapable = FALSE;
194 #if defined(APDK_VIP_COLORFILTERING)
195 Config.bErnie = FALSE;
197 Config.bColorImage = FALSE;
198 theQuality = qualityNormal;
200 pmQuality = QUALITY_NORMAL;
201 Config.bColorImage = FALSE;
202 #ifdef APDK_AUTODUPLEX
203 bDuplexCapable = TRUE;
207 LJJetReadyBestColorMode::LJJetReadyBestColorMode () : PrintMode (NULL)
214 bFontCapable = FALSE;
216 #if defined(APDK_VIP_COLORFILTERING)
217 Config.bErnie = FALSE; // Raghu
220 Config.bColorImage = FALSE;
221 theQuality = qualityPresentation;
222 pmQuality = QUALITY_BEST;
223 #ifdef APDK_AUTODUPLEX
224 bDuplexCapable = TRUE;
228 LJJetReadyGrayMode::LJJetReadyGrayMode () : PrintMode (NULL)
235 bFontCapable = FALSE;
237 #if defined(APDK_VIP_COLORFILTERING)
238 Config.bErnie = FALSE; // Raghu
241 Config.bColorImage = FALSE;
243 #ifdef APDK_AUTODUPLEX
244 bDuplexCapable = TRUE;
248 LJJetReadyBestGrayMode::LJJetReadyBestGrayMode () : PrintMode (NULL)
255 bFontCapable = FALSE;
257 #if defined(APDK_VIP_COLORFILTERING)
258 Config.bErnie = FALSE; // Raghu
261 Config.bColorImage = FALSE;
263 pmQuality = QUALITY_BEST;
264 theQuality = qualityPresentation;
265 #ifdef APDK_AUTODUPLEX
266 bDuplexCapable = TRUE;
270 HeaderLJJetReady::HeaderLJJetReady (Printer* p, PrintContext* pc)
276 DRIVER_ERROR HeaderLJJetReady::Send ()
283 DRIVER_ERROR HeaderLJJetReady::StartSend ()
286 char szScratchStr[64];
288 err = thePrinter->Send ((const BYTE*)ccpPJLStartJob, sizeof(ccpPJLStartJob));
291 //Send the UTF8 encoding command
292 err = thePrinter->Send ((const BYTE*)ccpPJLUTF8, sizeof(ccpPJLUTF8));
295 // If it is Grayscale printjob, send the PJL command indicating the same
296 COLORMODE eC = COLOR;
301 ((LJJetReady *)thePrinter)->bGrey_K = FALSE;
302 if ((thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD)) == NO_ERROR &&
305 ((LJJetReady *)thePrinter)->bGrey_K = TRUE;
306 err = thePrinter->Send ((const BYTE*)ccpPJLSetPlanes,sizeof(ccpPJLSetPlanes));
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));
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)
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
326 strcat (szScratchStr, "SHORTEDGE\015\012");
329 err = thePrinter->Send ((const BYTE *) szScratchStr, strlen (szScratchStr));
332 //Set the resolution to 600
333 err = thePrinter->Send ((const BYTE*)ccpPJLSetRes,sizeof(ccpPJLSetRes));
336 //Send the time out command
337 err = thePrinter->Send ((const BYTE*)ccpPJLSetTO,sizeof(ccpPJLSetTO));
340 //send the mojave PCL_XL_ENTER_LANG command
341 err = thePrinter->Send ((const BYTE*)ccpPCLEnterXL,sizeof(ccpPCLEnterXL));
344 //send the comment string
345 err = thePrinter->Send ((const BYTE*)ccpPJLComment,sizeof(ccpPJLComment));
348 err = thePrinter->Send ((const BYTE*)JrBeginSessionSeq,sizeof(JrBeginSessionSeq));
354 int HeaderLJJetReady::JRPaperToMediaSize(PAPER_SIZE psize)
358 case LETTER: return 0;
359 case LEGAL: return 1;
363 case OUFUKU: return 14;
364 case HAGAKI: return 14;
366 #ifdef APDK_EXTENDED_MEDIASIZE
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;
381 DRIVER_ERROR HeaderLJJetReady::StartPage ()
384 BYTE szCustomSize[64];
386 /* Orienatation: is JrFeedOrientationSeq[1]. Can take the following values:
389 Reversed Portrait : 0x02
390 Reversed Landscape : 0x03
391 Image Orientataion: 0x04
393 Mojave supports only one feed orientation: Portrait
395 err = thePrinter->Send ((const BYTE*)JrFeedOrientationSeq,sizeof(JrFeedOrientationSeq));
399 PAPER_SIZE ps = thePrintContext->GetPaperSize ();
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
407 BYTE szScratchStr[] = {"\xF8\x2F\xC0\x00\xF8\x30"};
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);
431 err = thePrinter->Send (szScratchStr, sizeof (szScratchStr));
437 err = thePrinter->Send ((const BYTE*)JrPaperSizeSeq,sizeof(JrPaperSizeSeq));
441 // If it is Grayscale printjob, send the PJL command indicating the same
442 COLORMODE eC = COLOR;
447 thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD);
450 * Send Printable Area. This is necessary in case source width is less than printable width.
453 * width is imagewidth - multiple of 96
454 * height is physical page height - margins for 8x5 x 11 - 6600 - 200 = 6400
457 BYTE szPrintableArea[] = {"\xD1\x00\x00\x00\x00\xF8\x74"};
458 int iWidth = (int) thePrintContext->InputPixelsPerRow ();
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.
469 iWidth = (int) (thePrintContext->PrintableWidth () *
470 thePrintContext->EffectiveResolutionX ());
474 * The minimum printable width is 1600 pixels (3 inch * 600 - 200 for margins)
483 * Further, source width must be a multiple of 32.
487 iWidth = ((iWidth + 31) / 32) * 32;
489 iPageHeight = (int) (thePrintContext->PrintableHeight () *
490 thePrintContext->EffectiveResolutionY ());
491 iPageHeight = ((iPageHeight + (MOJAVE_STRIP_HEIGHT - 1)) / MOJAVE_STRIP_HEIGHT) * MOJAVE_STRIP_HEIGHT;
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);
500 //MapPCLMediaTypeToString (eM); // Optional. No need to send
502 err = thePrinter->Send ((const BYTE *)JrBeginPageSeq, sizeof(JrBeginPageSeq));
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
510 // indicates switch to monochrome mode
511 err = thePrinter->Send ((const BYTE *) "\xC0\x07\xF8\x03\x6A", 5);
516 // indicates switch Color mode
517 err = thePrinter->Send ((const BYTE *) "\xC0\x06\xF8\x03\x6A", 5);
526 DRIVER_ERROR HeaderLJJetReady::EndPage ()
530 err = thePrinter->Send ((const BYTE*)JrVUExtn_3Seq,sizeof(JrVUExtn_3Seq));
532 err = thePrinter->Send ((const BYTE*)JrVU_ver_TagSeq,sizeof(JrVU_ver_TagSeq));
534 err = thePrinter->Send ((const BYTE*)JrVenUniqSeq,sizeof(JrVenUniqSeq));
536 err = thePrinter->Send ((const BYTE*)JrEndPageSeq,sizeof(JrEndPageSeq));
543 //-----------------------------------------------------------------------------
544 // Function: CDJPcl::MapPCLMediaTypeToString()
546 // Description: Sends the command for mediatype.
553 // Postcond: The mediatype commands are sent
557 //-----------------------------------------------------------------------------
558 DRIVER_ERROR HeaderLJJetReady::MapPCLMediaTypeToString (MEDIATYPE eM)
561 BYTE szPlain[] = {"\xC8\xC1\x05\x00Plain\xF8\x27"};
562 BYTE szPhoto[] = {"\xC8\xC1\x05\x00Gloss\xF8\x27"};
567 err = thePrinter->Send (szPlain, sizeof (szPlain));
572 err = thePrinter->Send (szPhoto, sizeof (szPhoto));
576 //** unsupported media type; return error code
579 break;// to be verified..
585 DRIVER_ERROR HeaderLJJetReady::EndJob ()
587 DRIVER_ERROR err = NO_ERROR;
589 err = thePrinter->Send((const BYTE*)JrEndSessionSeq, sizeof(JrEndSessionSeq));
592 err = thePrinter->Send((const BYTE*)ccpPJLExitSeq, sizeof(ccpPJLExitSeq));
598 DRIVER_ERROR HeaderLJJetReady::FormFeed ()
600 DRIVER_ERROR err = NO_ERROR;
601 ModeJPEG *pCompressor;
602 LJJetReady *thisPrinter = (LJJetReady *) thePrinter;
605 iPageHeight = (int) (thePrintContext->PrintableHeight () *
606 thePrintContext->EffectiveResolutionY ());
607 iPageHeight = ((iPageHeight + MOJAVE_STRIP_HEIGHT - 1) / MOJAVE_STRIP_HEIGHT) * MOJAVE_STRIP_HEIGHT;
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.
615 pCompressor = (ModeJPEG *) thisPrinter->GetCompressor ();
616 err = pCompressor->SendWhiteStrips (iPageHeight, thisPrinter->bGrey_K);
623 thisPrinter->m_bStartPageNotSent = TRUE;
627 DRIVER_ERROR HeaderLJJetReady::SendCAPy (unsigned int iAbsY)
632 DRIVER_ERROR LJJetReady::Encapsulate (const RASTERDATA* InputRaster, BOOL bLastPlane)
635 BYTE *pDataPtr = NULL;
638 //if (m_bStartPageNotSent)
640 // err = phLJJetReady->StartPage ();
641 // if (err != NO_ERROR)
643 // m_bStartPageNotSent = FALSE;
647 unsigned short int wCoordinate;
649 unsigned long ulVUDataLength = 0;
651 // For color JPEG, you need to skip the header information of 623 bytes
653 int iJpegHeaderSize = 623;
655 if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
663 ulVUDataLength = InputRaster->rastersize[COLORTYPE_COLOR];
664 pDataPtr = (BYTE *) InputRaster->rasterdata[COLORTYPE_COLOR];
668 ulVUDataLength = InputRaster->rastersize[COLORTYPE_COLOR] - iJpegHeaderSize;
669 pDataPtr = (BYTE *) InputRaster->rasterdata[COLORTYPE_COLOR] + iJpegHeaderSize;
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));
678 ModeJPEG *pCompressor = NULL;
679 pCompressor = (ModeJPEG*)GetCompressor();
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);
688 BYTE JrStripHeight[] = {0xF8,0x6D,0xC1,0x80,0x00,0xF8,0x63};
689 err = Send ((const BYTE *)JrStripHeight, sizeof(JrStripHeight));
692 BYTE JrTextObjectTypeSeq[] = {0xC0,0x00, 0xF8, 0x96};
693 err = Send ((const BYTE *)JrTextObjectTypeSeq, sizeof(JrTextObjectTypeSeq));
696 err = Send ((const BYTE *)JrVU_ver_TagSeq, sizeof(JrVU_ver_TagSeq));
699 err = Send ((const BYTE *) "\xC2", 1);
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);
712 if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
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);
725 err = Send (res, 13);
728 err = Send (pDataPtr, ulVUDataLength);
734 Header* LJJetReady::SelectHeader (PrintContext *pc)
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.
743 COLORMODE eC = COLOR;
748 thePrintContext = pc;
749 phLJJetReady = new HeaderLJJetReady (this, pc);
750 pc->GetPrintModeSettings (eQ, eM, eC, bD);
751 if (eQ == QUALITY_BEST)
753 m_eCompressMode = COMPRESS_MODE_LJ;
757 if (HPLJJRCompress && m_eCompressMode != COMPRESS_MODE_LJ)
759 dlclose (m_hHPLibHandle);
760 m_hHPLibHandle = NULL;
761 HPLJJRCompress = NULL;
767 DRIVER_ERROR LJJetReady::VerifyPenInfo()
773 DRIVER_ERROR LJJetReady::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
780 Compressor* LJJetReady::CreateCompressor (unsigned int RasterSize)
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
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).
796 RasterSize = (int) (thePrintContext->PrintableWidth () * thePrintContext->EffectiveResolutionX ()) * 3;
799 if (RasterSize < 4800)
805 * Further, source width must be a multiple of 32 (96 for RGB here).
808 RasterSize = ((RasterSize + 95) / 96) * 96;
810 m_pCompressor = new ModeJPEG (pSS, this, RasterSize, m_eCompressMode);
811 return m_pCompressor;
815 * Function name: ParseError
817 * Owner: Darrell Walker
819 * Purpose: To determine what error state the printer is in.
823 * Parameters on entry: status_reg is the contents of the centronics
824 * status register (at the time the error was
827 * Parameters on exit: unchanged
829 * Return Values: The proper DISPLAY_STATUS to reflect the printer
833 DISPLAY_STATUS LJJetReady::ParseError(BYTE status_reg)
835 DBG1("LJJetReady: parsing error info\n");
837 DRIVER_ERROR err = NO_ERROR;
838 BYTE szReadBuff[256];
839 DWORD iReadCount = 256;
840 DISPLAY_STATUS eStatus = (DISPLAY_STATUS) status_reg;
847 memset (szReadBuff, 0, 256);
848 err = pSS->FromDevice (szReadBuff, &iReadCount);
849 if (err == NO_ERROR && iReadCount == 0)
852 if (strstr ((char *) szReadBuff, "JOB"))
854 if (!(tmpStr = strstr ((char *) szReadBuff, "NAME")))
855 return DISPLAY_PRINTING;
857 while (*tmpStr < '0' || *tmpStr > '9')
859 sscanf (tmpStr, "%d", &iErrorCode);
860 if (iErrorCode != (long) (this))
861 return DISPLAY_PRINTING;
864 if (strstr ((char *) szReadBuff, "END"))
866 return DISPLAY_PRINTING_COMPLETE;
870 if (strstr ((char *) szReadBuff, "CANCEL"))
871 return DISPLAY_PRINTING_CANCELED;
873 if (!(tmpStr = strstr ((char *) szReadBuff, "CODE")))
877 while (*tmpStr < '0' || *tmpStr > '9')
879 sscanf (tmpStr, "%d", &iErrorCode);
881 if (iErrorCode < 32000)
882 return DISPLAY_PRINTING;
884 if (iErrorCode == 40010 || iErrorCode == 40020)
885 return DISPLAY_NO_PENS; // Actually, out of toner
887 if (iErrorCode == 40021)
888 return DISPLAY_TOP_COVER_OPEN;
890 if ((iErrorCode / 100) == 419)
891 return DISPLAY_OUT_OF_PAPER;
893 if ((iErrorCode / 1000) == 42 || iErrorCode == 40022)
895 DBG1("Paper Jammed\n");
896 return DISPLAY_PAPER_JAMMED;
899 if (iErrorCode > 40049 && iErrorCode < 41000)
902 return DISPLAY_ERROR_TRAP;
905 if (iErrorCode == 40079)
906 return DISPLAY_OFFLINE;
908 return DISPLAY_ERROR_TRAP;
911 BYTE * ModeJPEG::fpJPEGBuffer = NULL; // image buffer
912 DWORD ModeJPEG::fJPEGBufferPos; // position of 1'st empty byte in image buffer
914 void ModeJPEG::jpeg_flush_output_buffer_callback(JOCTET *outbuf, BYTE* buffer, DWORD size)
916 fJPEGBufferPos += size;
917 memcpy (fpJPEGBuffer, buffer, size);
918 fpJPEGBuffer += size;
921 //----------------------------------------------------------------
922 // These are "overrides" to the JPEG library error routines
923 //----------------------------------------------------------------
924 static void Gjpeg_error (j_common_ptr cinfo)
926 // The standard behavior is to send a message to stderr.
929 void ModeJPEG::SetBuffer(BYTE * pJPEGBuffer)
931 fpJPEGBuffer = pJPEGBuffer;
934 DWORD ModeJPEG::GetJPEGBufferSize() const
936 return fJPEGBufferPos;
940 BYTE* ModeJPEG::GetBuffer()
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
952 #define ConvertToGrayMacro(red, green, blue) ((unsigned char)( ( (red * 30) + (green * 59) + (blue * 11) ) / 100 ))
954 //--------------------------------------------------------------------
955 // Function: ModeJPEG::ModeJPEG
957 // Release: [PROTO4_1]
959 // Description: Preferred ctor
961 // Input: padMultiple - the fBufferDataLength returned from
962 // GetRow must be divisible by this value.
964 // Modifies: fpBuffer
972 // Created: 11/07/96 cal
973 // Last Modified: 5/020/01 DG
974 //--------------------------------------------------------------------
977 SystemServices* pSys,
979 unsigned int PlaneSize,
980 COMPRESS_MODE eCompressMode
982 Compressor(pSys, PlaneSize, TRUE),
983 thePrinter(pPrinter) // needed by Flush
985 if (constructor_error != NO_ERROR) // if error in base constructor
989 fpJPEGBuffer = NULL; // image buffer
990 fJPEGBufferPos = 0; // position of 1'st empty byte in image buffer
993 m_SourceBitmap.pvBits = (BYTE*) new BYTE[(inputsize * MOJAVE_STRIP_HEIGHT)];
995 if (m_SourceBitmap.pvBits == NULL)
997 constructor_error = ALLOCMEM_ERROR;
1001 memset (m_SourceBitmap.pvBits, 0xFF, inputsize * MOJAVE_STRIP_HEIGHT);
1003 m_SourceBitmap.cjBits = 0;
1004 m_SourceBitmap.bitmapInfo.bmiHeader.biWidth = 0;
1005 m_SourceBitmap.bitmapInfo.bmiHeader.biHeight = 0;
1008 m_DestBitmap.pvBits = NULL;
1009 m_DestBitmap.cjBits = 0;
1010 m_DestBitmap.bitmapInfo.bmiHeader.biWidth = 0;
1011 m_DestBitmap.bitmapInfo.bmiHeader.biHeight = 0;
1013 m_lCurrCDRasterRow = 0;
1014 m_lPrinterRasterRow = 0;
1016 m_iRasterWidth = inputsize / 3;
1021 m_eCompressMode = eCompressMode;
1023 } // ModeJPEG::ModeJPEG
1026 //--------------------------------------------------------------------
1027 // Function: ModeJPEG::~ModeJPEG
1029 // Release: [PROTO4_1]
1031 // Description: Destructor.
1035 // Modifies: fpBuffer - deletes the buffer
1036 // ?? - deletes other buffer(s)??
1044 // Created: 11/07/96 cal
1045 // Last Modified: 5/020/01 DG
1046 //--------------------------------------------------------------------
1047 ModeJPEG::~ModeJPEG ()
1049 if (m_SourceBitmap.pvBits)
1051 delete m_SourceBitmap.pvBits;
1052 m_SourceBitmap.pvBits = NULL;
1055 if (m_DestBitmap.pvBits)
1057 delete m_DestBitmap.pvBits;
1058 m_DestBitmap.pvBits = NULL;
1061 } // ModeJPEG::~ModeJPEG
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
1069 DRIVER_ERROR ModeJPEG::SendWhiteStrips (int iPageHeight, BOOL bGray)
1071 DRIVER_ERROR err = NO_ERROR;
1072 HPLJBITMAP hWhiteBitmap;
1073 QTABLEINFO qTableInfo;
1074 RASTERDATA whiteRaster;
1076 qTableInfo.qFactor = 6;
1078 hWhiteBitmap.pvBits = NULL;
1082 m_SourceBitmap.cjBits = m_iRasterWidth * MOJAVE_STRIP_HEIGHT;
1083 memset (m_SourceBitmap.pvBits, 0x00, m_SourceBitmap.cjBits);
1087 m_SourceBitmap.cjBits = m_iRasterWidth * MOJAVE_STRIP_HEIGHT * 3;
1088 memset (m_SourceBitmap.pvBits, 0xFF, m_SourceBitmap.cjBits);
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)
1100 thePrinter->Encapsulate (&whiteRaster, TRUE);
1101 m_lPrinterRasterRow += MOJAVE_STRIP_HEIGHT;
1107 BOOL ModeJPEG::Compress( HPLJBITMAP *pSrcBitmap,
1108 HPLJBITMAP *pTrgBitmap,
1109 QTABLEINFO *pQTable,
1115 if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
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)
1124 if (bGrayscaleSet)
\r
1126 BYTE *p = pSrcBitmap->pvBits;
\r
1127 for (int j = 0; j < pSrcBitmap->bitmapInfo.bmiHeader.biHeight; j++)
\r
1129 for (int i = 0; i < pSrcBitmap->bitmapInfo.bmiHeader.biWidth; i++)
\r
1131 p[0] = ConvertToGrayMacro (p[0], p[1], p[2]);
\r
1137 iRet = HPLJJRCompress (pTrgBitmap->pvBits, (uint32_t *) &pTrgBitmap->cjBits, pSrcBitmap->pvBits,
1138 pSrcBitmap->bitmapInfo.bmiHeader.biWidth, pSrcBitmap->bitmapInfo.bmiHeader.biHeight);
1143 #endif // HAVE_LIBDL
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");
1155 hp_rgb_ycc_setup (1); // Use modified Mojave CSC table
\r
1157 //----------------------------------------------------------------
1158 // Setup for compression
1159 //----------------------------------------------------------------
1161 //----------------------------------------------------------------
1162 // JPEG Lib Step 1: Allocate and initialize JPEG compression object
1163 //----------------------------------------------------------------
1164 cinfo.err = jpeg_std_error( &jerr );
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)) {
1173 // If we get here, the JPEG code has signaled an error.
1174 //* We need to clean up the JPEG object, and return.
1176 jpeg_destroy_compress(&cinfo);
1180 jpeg_create_compress( &cinfo );
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 //----------------------------------------------------------------
1190 //----------------------------------------------------------------
1191 // JPEG Lib Step 3: Set parameters for compression, including image size & colorspace
1192 //----------------------------------------------------------------
1198 cinfo.in_color_space = JCS_GRAYSCALE;
\r
1203 cinfo.in_color_space = JCS_RGB; // arbitrary guess
\r
1206 jpeg_set_defaults( &cinfo );
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;
1214 // Create a static quant table here.
1216 static unsigned int mojave_quant_table1[64] = { 2,3,4,5,5,5,5,5,
1225 // Use this variable for representing the scale_factor for now.
1227 unsigned int iScaleFactor = pQTable->qFactor;
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.
1242 // Please refer to sRGBLaserHostBasedSoftwareERS.doc v9.0 section 5.2.5.3.1.1
1243 // for more details.
1245 // [NOTE] These loop needs to be further optimized.
1247 for (int i = 0; i < 3; i++)
1252 jpeg_add_quant_table(&cinfo, i, mojave_quant_table1, 0, FALSE );
1254 // Scaling the Q-Table elements.
1255 // Reset the element to 255, if it is greater than 255.
1257 for(int j = 1; j < 64; j++)
1259 cinfo.quant_tbl_ptrs[i]->quantval[j] = (UINT16)((mojave_quant_table1[j] * iScaleFactor) & 0xFF);
1261 } // for (int j = 1; j < 64; j++)
1263 // Special scaling for first 6 elements in the table.
1264 // Reset the specially scaled elements 255, if it is greater than 255.
1268 // 1st component in the table. Unchanged, I need not change anything here.
1270 cinfo.quant_tbl_ptrs[i]->quantval[0] = (UINT16)mojave_quant_table1[0];
1273 // 2nd and 3rd components in the zig zag order
1275 // The following dTemp is being used to ceil the vales: e.g 28.5 to 29
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;
1280 dTemp = mojave_quant_table1[8] * (1 + 0.25 * (iScaleFactor - 1)) + 0.5;
1281 cinfo.quant_tbl_ptrs[i]->quantval[8] = (UINT16)dTemp & 0xFF;
1284 // 4th, 5th and 6th components in the zig zag order
1286 dTemp = mojave_quant_table1[16] * (1 + 0.50 * (iScaleFactor - 1)) + 0.5;
1287 cinfo.quant_tbl_ptrs[i]->quantval[16] = (UINT16)dTemp & 0xFF;
1289 dTemp = mojave_quant_table1[9] * (1 + 0.50 * (iScaleFactor - 1)) + 0.5;
1290 cinfo.quant_tbl_ptrs[i]->quantval[9] = (UINT16)dTemp & 0xFF;
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++)
1297 // Hard code to use sampling mode 4:4:4
1299 cinfo.comp_info[0].h_samp_factor = 1;
1300 cinfo.comp_info[0].v_samp_factor = 1;
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)
1306 //ERR(("JPEGCompress: Not enough memory\n"));
1310 fpJPEGStart = fpJPEGBuffer;
1312 jpeg_buffer_dest(&cinfo, (JOCTET *) fpJPEGBuffer, (void*) (ModeJPEG::jpeg_flush_output_buffer_callback));
1315 cinfo.write_JFIF_header =
1316 cinfo.write_Adobe_marker = FALSE;
1317 jpeg_suppress_tables(&cinfo, TRUE);
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 //----------------------------------------------------------------
1328 jpeg_start_compress( &cinfo, TRUE );
1331 //----------------------------------------------------------------
1332 // This completes the JPEG setup.
1333 //----------------------------------------------------------------
1336 // do the jpeg compression
1337 JSAMPROW pRowArray[1];
1338 BYTE* pCurLine = (BYTE*) pSrcBitmap->pvBits;
1341 dwScanLine = cinfo.image_width * iColorsUsed;
1343 for(unsigned int nrow = 0; nrow < cinfo.image_height; nrow++)
1345 pRowArray[0] = (JSAMPROW) pCurLine;
1346 jpeg_write_scanlines(&cinfo, pRowArray, 1);
1347 pCurLine += dwScanLine;
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 );
1357 // Read the quantization tables used for the compression.
1360 if (cinfo.quant_tbl_ptrs[0] != NULL)
1362 for (int iI = 0; iI < QTABLE_SIZE; iI++)
1364 pQTable->qtable0[iI] = (DWORD)cinfo.quant_tbl_ptrs[0]->quantval[iI];
1369 if (cinfo.quant_tbl_ptrs[1] != NULL)
1371 for (int iI = 0; iI < QTABLE_SIZE; iI++)
1373 pQTable->qtable1[iI] = (DWORD)cinfo.quant_tbl_ptrs[1]->quantval[iI];
1377 if (cinfo.quant_tbl_ptrs[2] != NULL)
1379 for (int iI = 0; iI < QTABLE_SIZE; iI++)
1381 pQTable->qtable2[iI] = (DWORD)cinfo.quant_tbl_ptrs[2]->quantval[iI];
1386 //----------------------------------------------------------------
1387 // JPEG Lib Step 7: Destroy the compression object
1388 //----------------------------------------------------------------
1389 jpeg_destroy_compress( &cinfo );
1391 memcpy(pTrgBitmap, pSrcBitmap, sizeof(HPLJBITMAP));
1393 #ifdef JPEG_FILE_OUTPUT
1394 fwrite(fpJPEGStart, sizeof(BYTE), GetJPEGBufferSize(), pFile);
1397 if(fpJPEGStart && bGrayscaleSet)
1399 long lBufferSize = GetJPEGBufferSize();
1401 while (l < lBufferSize)
1403 if(fpJPEGStart[l] == 0xFF && fpJPEGStart[l+1] == 0xDA)
1407 if(l != lBufferSize)
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;
1416 pTrgBitmap->pvBits = (BYTE*)fpJPEGStart;
1421 pTrgBitmap->pvBits = (BYTE*) fpJPEGStart;
1422 pTrgBitmap->cjBits = GetJPEGBufferSize();
1425 #ifdef JPEG_FILE_OUTPUT
1433 BOOL ModeJPEG::Process
1438 DRIVER_ERROR err = NO_ERROR;
1441 (input->rasterdata[COLORTYPE_COLOR]==NULL && input->rasterdata[COLORTYPE_BLACK]==NULL)) // flushing pipeline
1445 if (input->rasterdata[COLORTYPE_COLOR])
1447 if (m_lCurrCDRasterRow < MOJAVE_STRIP_HEIGHT )
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 ++;
1454 if (m_lCurrCDRasterRow == MOJAVE_STRIP_HEIGHT || ((LJJetReady*)thePrinter)->phLJJetReady->IsLastBand())
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;
1461 QTABLEINFO qTableInfo;
1462 BOOL bGrayScaleSet = ((LJJetReady *)thePrinter)->bGrey_K;
1465 qTableInfo.qFactor = 6;
1466 if (((LJJetReady*)thePrinter)->m_bStartPageNotSent)
1468 err = (((LJJetReady*)thePrinter)->phLJJetReady)->StartPage();
1469 ((LJJetReady*)thePrinter)->m_bStartPageNotSent = FALSE;
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));
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) )
1485 sourceheight = ( (sourceheight / MOJAVE_STRIP_HEIGHT) + 1) * MOJAVE_STRIP_HEIGHT;
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);
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));
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);
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));
1514 unsigned short int stripcount = sourceheight / MOJAVE_STRIP_HEIGHT;
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);
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));
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));
1539 // 0x00 indicates grayscale printing
1540 BYTE JrGrayScaleSeq[] = {0xC0,0x00,0xF8,0x97};
1541 err = thePrinter->Send ((const BYTE *)JrGrayScaleSeq, sizeof(JrGrayScaleSeq));
1546 // 0x04 indicates Color printing
1547 BYTE JrColorSeq[] = {0xC0,0x04,0xF8,0x97};
1548 err = thePrinter->Send ((const BYTE *)JrColorSeq, sizeof(JrColorSeq));
1552 // Interleaved Color Enumeration for Mojave
1553 BYTE JrSeq[] = {0xC0,0x00,0xF8,0x98};
1554 err = thePrinter->Send ((const BYTE *)JrSeq, sizeof(JrSeq));
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));
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};
1572 if (HPLJJRCompress && m_eCompressMode == COMPRESS_MODE_LJ)
1574 JrDataLengthSeq[1] = 0;
1575 JrDataLengthSeq[2] = 0;
1578 err = thePrinter->Send ((const BYTE *)JrDataLengthSeq, sizeof(JrDataLengthSeq));
1581 bRet = Compress (&m_SourceBitmap,
1584 FALSE // We are only worried about the qTables not about the colorspace.
1586 if (!HPLJJRCompress || (HPLJJRCompress && m_eCompressMode != COMPRESS_MODE_LJ))
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));
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);
1600 //VWritePrinter((VOID*) pQTableInfo->qtable1, sizeof(DWORD) * QTABLE_SIZE);
1601 err = thePrinter->Send ((const BYTE *)qTableInfo.qtable1, sizeof(DWORD) * QTABLE_SIZE);
1604 //VWritePrinter((VOID*) pQTableInfo->qtable2, sizeof(DWORD) * QTABLE_SIZE);
1605 err = thePrinter->Send ((const BYTE *)qTableInfo.qtable2, sizeof(DWORD) * QTABLE_SIZE);
1608 BYTE szStr[sizeof (DWORD) * QTABLE_SIZE * 3];
1611 for (int i = 0; i < QTABLE_SIZE; i++)
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;
1618 for (int i = 0; i < QTABLE_SIZE; i++)
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;
1625 for (int i = 0; i < QTABLE_SIZE; i++)
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;
1632 err = thePrinter->Send ((const BYTE *) szStr, 3 * sizeof (DWORD) * QTABLE_SIZE);
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
1641 // Color 0x6614_E001
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));
1651 //VWritePrinter("\x05\xE0\x00\x00", 0x4);
1652 BYTE JrCR1GSeq[] = {0x05,0xE0,0x00,0x00};
1653 err = thePrinter->Send ((const BYTE *)JrCR1GSeq, sizeof(JrCR1GSeq));
1658 //VWritePrinter("\x01\xE0\x14\x66", 0x4);
1659 BYTE JrCR1CSeq[] = {0x01,0xE0,0x14,0x66};
1660 err = thePrinter->Send ((const BYTE *)JrCR1CSeq, sizeof(JrCR1CSeq));
1666 // Color 0x0000_0001
1668 // bit 0 = convert rgb data
1669 // bit 1: 0 = 13 bit precision
1670 // 1 = 14 bit precision
1674 //VWritePrinter("\x00\x00\x00\x00", 0x4);
1675 BYTE JrCR3GSeq[] = {0x00,0x00,0x00,0x00};
1677 err = thePrinter->Send ((const BYTE *)JrCR3GSeq, sizeof(JrCR3GSeq));
1682 //VWritePrinter("\x01\x00\x00\x00", 0x4);
1683 BYTE JrCR3CSeq[] = {0x01,0x00,0x00,0x00};
1684 err = thePrinter->Send ((const BYTE *)JrCR3CSeq, sizeof(JrCR3CSeq));
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
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));
1700 //VWritePrinter("\x00\x00\x00\x00", 0x4);
1701 BYTE JrCSC2Seq[] = {0x00,0x00,0x00,0x00};
1702 err = thePrinter->Send ((const BYTE *)JrCSC2Seq, sizeof(JrCSC2Seq));
1705 //VWritePrinter("\x00\x00\x00\x00", 0x4);
1706 BYTE JrCSC3Seq[] = {0x00,0x00,0x00,0x00};
1707 err = thePrinter->Send ((const BYTE *)JrCSC3Seq, sizeof(JrCSC3Seq));
1710 //VWritePrinter("\x00\x20\x00\x00", 0x4);
1711 BYTE JrCSC4Seq[] = {0x00,0x20,0x00,0x00};
1712 err = thePrinter->Send ((const BYTE *)JrCSC4Seq, sizeof(JrCSC4Seq));
1715 //VWritePrinter("\x00\xE0\x00\x00", 0x4);
1716 BYTE JrCSC5Seq[] = {0x00,0xE0,0x00,0x00};
1717 err = thePrinter->Send ((const BYTE *)JrCSC5Seq, sizeof(JrCSC5Seq));
1720 //VWritePrinter("\x00\x00\x00\x00", 0x4);
1721 BYTE JrCSC6Seq[] = {0x00,0x00,0x00,0x00};
1722 err = thePrinter->Send ((const BYTE *)JrCSC6Seq, sizeof(JrCSC6Seq));
1725 //VWritePrinter("\x00\x20\x00\x00", 0x4);
1726 BYTE JrCSC7Seq[] = {0x00,0x20,0x00,0x00};
1727 err = thePrinter->Send ((const BYTE *)JrCSC7Seq, sizeof(JrCSC7Seq));
1730 //VWritePrinter("\x00\x00\x00\x00", 0x4);
1731 BYTE JrCSC8Seq[] = {0x00,0x00,0x00,0x00};
1732 err = thePrinter->Send ((const BYTE *)JrCSC8Seq, sizeof(JrCSC8Seq));
1735 //VWritePrinter("\x00\xE0\x00\x00", 0x4);
1736 BYTE JrCSC9Seq[] = {0x00,0xE0,0x00,0x00};
1737 err = thePrinter->Send ((const BYTE *)JrCSC9Seq, sizeof(JrCSC9Seq));
1739 } // if (!HPLJJRCompress)
1740 } // if (....bStartPageNotSent)
1744 HPLJBITMAP jpegGrayBitmap;
1746 jpegGrayBitmap.pvBits = NULL;
1748 // Convert 24bpp Gray to 8bpp Gray.
1749 // JPEG takes K 8bpp gray data. We are using two different buffers for these.
1751 if(bGrayScaleSet && m_eCompressMode == COMPRESS_MODE_JPEG)
1753 pbTemp = (BYTE*)m_SourceBitmap.pvBits;
1755 jpegGrayBitmap.pvBits = new BYTE[m_SourceBitmap.cjBits / 3];
1757 for(long i = 0, j=0; i < (long)m_SourceBitmap.cjBits; i += 3, j++)
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];
1764 jpegGrayBitmap.pvBits[j] = pbTemp[i];
1768 if (m_DestBitmap.pvBits)
1770 delete m_DestBitmap.pvBits;
1771 m_DestBitmap.pvBits = NULL;
1774 // JPEG grayscale specific operations are done here.
1776 if(bGrayScaleSet && m_eCompressMode == COMPRESS_MODE_JPEG)
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;
1784 if (bGrayScaleSet && m_eCompressMode == COMPRESS_MODE_JPEG)
1786 bRet = Compress (&jpegGrayBitmap, &m_DestBitmap, &qTableInfo,bGrayScaleSet);
1790 bRet = Compress (&m_SourceBitmap, &m_DestBitmap, &qTableInfo,bGrayScaleSet);
1793 m_SourceBitmap.cjBits = 0;
1794 m_SourceBitmap.bitmapInfo.bmiHeader.biWidth = 0;
1795 m_SourceBitmap.bitmapInfo.bmiHeader.biHeight = 0;
1797 memset(m_SourceBitmap.pvBits, 0xFF, inputsize * MOJAVE_STRIP_HEIGHT);
1799 if (jpegGrayBitmap.pvBits)
1801 delete jpegGrayBitmap.pvBits;
1802 jpegGrayBitmap.pvBits = NULL;
1804 m_lPrinterRasterRow += MOJAVE_STRIP_HEIGHT;
1806 m_lCurrCDRasterRow = 0;
1809 ((LJJetReady*)thePrinter)->phLJJetReady->SetLastBand(FALSE);
1820 BYTE* ModeJPEG::NextOutputRaster(COLORTYPE color)
1821 // since we return 1-for-1, just return result first call
1823 if (iRastersReady==0)
1826 if (color == COLORTYPE_BLACK)
1833 return m_DestBitmap.pvBits;
1837 unsigned int ModeJPEG::GetOutputWidth(COLORTYPE color)
1839 if (color == COLORTYPE_COLOR)
1841 return m_DestBitmap.cjBits;
1851 #endif // defined APDK_LJJetReady