1 /*****************************************************************************\
2   ljfastraster.cpp : Implimentation for the LJFastRaster class
3 
4   Copyright (c) 1996 - 2015, HP 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 HP 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_LJFASTRASTER
33 
34 #include "header.h"
35 #include "ljfastraster.h"
36 #include "printerproxy.h"
37 
38 APDK_BEGIN_NAMESPACE
39 
40 #define INDY_STRIP_HEIGHT	128			// Indy strips can't cross 128 boundary
41 
42 extern uint32_t ulMapDJ600_CCM_K[ 9 * 9 * 9 ];
43 
44 BYTE FrBeginSessionSeq[]				= {0xC0, 0x00, 0xF8, 0x86, 0xC0, 0x03, 0xF8, 0x8F, 0xD1, 0x58,
45 										    0x02, 0x58, 0x02, 0xF8, 0x89, 0x41};
46 BYTE FrFeedOrientationSeq[]				= {0xC0, 0x00  , 0xF8, 0x28 };
47 //											   |fd ori enum|       |ori cmd|
48 BYTE FrPaperSizeSeq[]					= {0xC0,  0x00      ,0xF8, 0x25};
49 //											   |pap siz enum|     |pap sz cmd|
50 BYTE FrMedSourceSeq[]					= {0xC0,  0x00      ,0xF8, 0x26        };
51 //											   |Med src enum|     |Med src cmd|
52 BYTE FrMedDestinationSeq[]				= {0xC0,  0x00        ,0xF8 , 0x24      };
53 //											   |Med Dest enum|      |Med src cmd|
54 BYTE FrBeginPageSeq[]				    = {0x43, 0xD3, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x2A, 0x75, 0xC0, 0x07,0xF8, 0x03, 0x6A,
55 											0xC0, 0xCC, 0xF8, 0x2C, 0x7B,
56 											0xD3, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x4C, 0x6B};
57 
58 BYTE FrBeginImageSeq[]				    = {0xC2, 0x00, 0x40, 0x70, 0x68, 0xF8, 0x91, 0xC1};
59 
60 BYTE FrVU_ver_TagSeq[]					= {0xC2, 0x00, 0x00, 0x04, 0x00 , 0xF8, 0x95			  };
61 //												|endian alignd         |  |Fr_ver_ tag|
62 BYTE FrDataLengthSeq[]					= {0xC2, 0x86, 0x0A, 0x00, 0x00, 0xF8, 0x92	  };
63 //																			  | VU data length|
64 BYTE FrVenUniqSeq[]						= {0x46};
65 BYTE FrVUExtn_3Seq[]					= {0xC2, 0x11, 0x20, 0x70, 0x68			,0xF8, 0x91	};
66 //												|endian alignd Fr rd img tag|	  |VU extensn|
67 BYTE FrOpenDataSourceSeq[]              = {0xC0, 0x00, 0xF8, 0x88, 0xC0, 0x01, 0xF8, 0x82, 0x48};
68 
69 BYTE FrEndPageSeq[]						=  {0x44};
70 BYTE FrEndSessionSeq[]					=  {0x42};
71 BYTE FrCloseDataSourceSeq[]				=  {0x49};
72 // PJL level commands..
73 
74 //**JETLIB ENTRIES
75 
76 const char *ccpPJLStartJob				= "\033%-12345X";
77 const char *ccpPJLExitSeq 				= "\033%-12345X@PJL EOJ\012\033%-12345X";
78 const char *ccpPJLSetRes				= "@PJL SET RESOLUTION=600\012";
79 const char *ccpPCLEnterXL				= "@PJL ENTER LANGUAGE=PCLXL\012";
80 const char *ccpPJLSetTO				    = "@PJL SET TIMEOUT=900\012";
81 const char *ccpUEL                      = "\033%-12345X";
82 const char *ccpPJLComment				= ") HP-PCL XL;2;0;Comment\012";
83 const char *ccpPJLSet1BPP				= "@PJL SET BITSPERPIXEL=1\012";
84 const char *ccpPJLSetECONOMODE			= "@PJL SET ECONOMODE=OFF\012";
85 const char *ccpPJLSetTimeStamp			= "@PJL SET JOBATTR=";
86 
87 //**END JETLIB ENTRIES
88 
89 
LJFastRaster(SystemServices * pSS,int numfonts,BOOL proto)90 LJFastRaster::LJFastRaster (SystemServices* pSS, int numfonts, BOOL proto)
91     : Printer(pSS, numfonts, proto)
92 {
93 
94     if ((!proto) && (IOMode.bDevID))
95     {
96         constructor_error = VerifyPenInfo();
97         CERRCHECK;
98     }
99     else ePen = BLACK_PEN;    // matches default mode
100 
101     pMode[DEFAULTMODE_INDEX] = new LJFastRasterNormalMode ();
102     pMode[GRAYMODE_INDEX]    = new LJFastRasterDraftMode ();
103     //pMode[DEFAULTMODE_INDEX]   = pMode[GRAYMODE_INDEX];
104     ModeCount = 2;
105 
106     CMYMap = NULL;
107     m_bJobStarted = FALSE;
108 #ifdef  APDK_AUTODUPLEX
109     m_bRotateBackPage = FALSE;  // Lasers don't require back side image to be rotated
110 #endif
111 
112     m_iYPos = 0;
113     m_bStartPageNotSent = TRUE;
114 
115     DBG1("LJFastRaster created\n");
116 }
117 
~LJFastRaster()118 LJFastRaster::~LJFastRaster ()
119 {
120     DISPLAY_STATUS  eDispStatus;
121     if (IOMode.bStatus && m_bJobStarted)
122     {
123         for (int i = 0; i < 5; i++)
124         {
125             pSS->BusyWait (2000);
126             eDispStatus = ParseError (0);
127             if (eDispStatus == DISPLAY_PRINTING_COMPLETE)
128             {
129                 pSS->DisplayPrinterStatus (eDispStatus);
130                 break;
131             }
132         }
133     }
134 }
135 
LJFastRasterNormalMode()136 LJFastRasterNormalMode::LJFastRasterNormalMode ()
137 : GrayMode(ulMapDJ600_CCM_K)
138 {
139     ResolutionX[0] = 600;
140     ResolutionY[0] = 600;
141     BaseResX = BaseResY = 600;
142 
143     MixedRes = FALSE;
144 
145 	theQuality = qualityNormal;
146 
147     pmQuality = QUALITY_NORMAL;
148 
149 #if defined(APDK_VIP_COLORFILTERING)
150     Config.bErnie = FALSE; // Raghu
151 #endif
152 
153 #ifdef APDK_AUTODUPLEX
154     bDuplexCapable = TRUE;
155 #endif
156 
157     bFontCapable = FALSE;
158 }
159 
LJFastRasterDraftMode()160 LJFastRasterDraftMode::LJFastRasterDraftMode ()
161 : GrayMode(ulMapDJ600_CCM_K)
162 {
163     ResolutionX[0] = 600;
164     ResolutionY[0] = 600;
165     BaseResX = BaseResY = 600;
166 
167     MixedRes = FALSE;
168 
169 	theQuality = qualityDraft;
170 
171     pmQuality = QUALITY_DRAFT;
172 
173 #if defined(APDK_VIP_COLORFILTERING)
174     Config.bErnie = FALSE; // Raghu
175 #endif
176 
177 #ifdef APDK_AUTODUPLEX
178     bDuplexCapable = TRUE;
179 #endif
180 
181     bFontCapable = FALSE;
182 }
183 
HeaderLJFastRaster(Printer * p,PrintContext * pc)184 HeaderLJFastRaster::HeaderLJFastRaster (Printer* p, PrintContext* pc)
185     : Header(p,pc)
186 {
187 	SetLastBand(FALSE);
188 }
189 
Send()190 DRIVER_ERROR HeaderLJFastRaster::Send ()
191 {
192     StartSend ();
193 
194     return NO_ERROR;
195 }
196 
StartSend()197 DRIVER_ERROR HeaderLJFastRaster::StartSend ()
198 {
199     DRIVER_ERROR    err = NO_ERROR;
200     char            res[64];
201 
202 	err = thePrinter->Send ((const BYTE*)ccpPJLStartJob, strlen (ccpPJLStartJob));
203 	ERRCHECK;
204 
205 	//Set the resolution to 600
206 	err = thePrinter->Send ((const BYTE*)ccpPJLSetRes, strlen (ccpPJLSetRes));
207 	ERRCHECK;
208 
209 	err = thePrinter->Send ((const BYTE*)ccpPJLSet1BPP, strlen (ccpPJLSet1BPP));
210 	ERRCHECK;
211 
212     QUALITY_MODE    eQ = QUALITY_NORMAL;
213     COLORMODE       eC;
214     MEDIATYPE       eM;
215     BOOL            bD;
216 
217     thePrintContext->GetPrintModeSettings (eQ, eM, eC, bD);
218 
219     strcpy (res, "@PJL SET ECONOMODE=");
220 
221     if (eQ == QUALITY_DRAFT)
222     {
223         strcat (res, "ON\015\012");
224     }
225     else
226     {
227         strcat (res, "OFF\015\012");
228     }
229     err = thePrinter->Send ((const BYTE *) res, strlen (res));
230     ERRCHECK;
231 
232 
233 	//Send the time out command
234 	err = thePrinter->Send ((const BYTE*)ccpPJLSetTO, strlen (ccpPJLSetTO));
235 	ERRCHECK;
236 
237 	//send the mojave PCL_XL_ENTER_LANG command
238 	err = thePrinter->Send ((const BYTE*)ccpPCLEnterXL, strlen (ccpPCLEnterXL));
239 	ERRCHECK;
240 
241 	//send the comment string
242 	err = thePrinter->Send ((const BYTE*)ccpPJLComment, strlen (ccpPJLComment));
243 	ERRCHECK;
244 
245 	err = thePrinter->Send ((const BYTE*)FrBeginSessionSeq,sizeof(FrBeginSessionSeq));
246 	ERRCHECK;
247 
248 	//** VU command to enable PCL-XL
249 	err = thePrinter->Send ((const BYTE*)FrVUExtn_3Seq,sizeof(FrVUExtn_3Seq));
250 	ERRCHECK;
251 	err = thePrinter->Send ((const BYTE*)FrVenUniqSeq,sizeof(FrVenUniqSeq));
252 	ERRCHECK;
253 
254     //----------------------------------------------------------------
255     // Open a data source, which will be kept open for the life
256     // of the session.  Any operators that need embedded data will
257     // use this data source.
258     //----------------------------------------------------------------
259  	err = thePrinter->Send ((const BYTE*)FrOpenDataSourceSeq,sizeof(FrOpenDataSourceSeq));
260 	ERRCHECK;
261 
262     return err;
263 }
264 
FrPaperToMediaSize(PAPER_SIZE psize)265 int HeaderLJFastRaster::FrPaperToMediaSize(PAPER_SIZE psize)
266 {
267     switch(psize)
268     {
269     case LETTER:        return 0;    break;
270     case LEGAL:         return 1;     break;
271     case A4:            return 2;          break;
272     case B4:            return 10;          break;
273     case B5:            return 11;          break;
274     case OUFUKU:        return 14;      break;
275     case HAGAKI:        return 14;      break;
276 	case A6:            return 17;      break;
277 #ifdef APDK_EXTENDED_MEDIASIZE
278     case A3:        return 5;      break;
279     case A5:        return 16;      break;
280     case LEDGER:        return 4;      break;
281     case EXECUTIVE:     return 3;   break;
282     case CUSTOM_SIZE:   return 96;      break;
283 	case ENVELOPE_NO_10: return 6;    break;
284 	case ENVELOPE_A2:    return 6;       break;
285 	case ENVELOPE_C6:    return 8;       break;
286 	case ENVELOPE_DL:    return 9;       break;
287 #endif
288     default:            return 0;    break;
289     }
290 }
291 
StartPage()292 DRIVER_ERROR HeaderLJFastRaster::StartPage ()
293 {
294     DRIVER_ERROR err;
295     BYTE    szCustomSize[16];
296 
297 	/* Orienatation: is FrFeedOrientationSeq[1]. Can take the following values:
298 		Portrait				: 0x00
299 		Landscape:				: 0x01
300 		Reversed    Portrait	: 0x02
301 		Reversed    Landscape	: 0x03
302 		Image		Orientataion: 0x04
303 	*/
304 	err = thePrinter->Send ((const BYTE*)FrFeedOrientationSeq,sizeof(FrFeedOrientationSeq));
305 	ERRCHECK;
306 
307 	//Put the papersize into the FrPaperSizeSeq[]
308 	PAPER_SIZE ps = thePrintContext->GetPaperSize ();
309 	int msizeCode = FrPaperToMediaSize(ps);
310 	FrPaperSizeSeq[1] = (BYTE) msizeCode;
311 #ifdef APDK_EXTENDED_MEDIASIZE
312 	if(msizeCode == 96 || msizeCode == 17) //Custom paper size or A6
313 	{
314         union
315         {
316             float       fValue;
317             uint32_t    uiValue;
318         } LJFUnion;
319         uint32_t    uiXsize;
320         uint32_t    uiYsize;
321         int         k = 0;
322         LJFUnion.fValue = (float) thePrintContext->PhysicalPageSizeX ();
323         uiXsize = LJFUnion.uiValue;
324         LJFUnion.fValue = (float) thePrintContext->PhysicalPageSizeY ();
325         uiYsize = LJFUnion.uiValue;
326         szCustomSize[k++] = 0xD5;
327         szCustomSize[k++] = (BYTE) (uiXsize & 0x000000FF);
328         szCustomSize[k++] = (BYTE) ((uiXsize & 0x0000FF00) >> 8);
329         szCustomSize[k++] = (BYTE) ((uiXsize & 0x00FF0000) >> 16);
330         szCustomSize[k++] = (BYTE) ((uiXsize & 0xFF000000) >> 24);
331         szCustomSize[k++] = (BYTE) (uiYsize & 0x000000FF);
332         szCustomSize[k++] = (BYTE) ((uiYsize & 0x0000FF00) >> 8);
333         szCustomSize[k++] = (BYTE) ((uiYsize & 0x00FF0000) >> 16);
334         szCustomSize[k++] = (BYTE) ((uiYsize & 0xFF000000) >> 24);
335         szCustomSize[k++] = 0xF8;
336         szCustomSize[k++] = 0x2F;
337         err = thePrinter->Send ((const BYTE *) szCustomSize, k);
338 		ERRCHECK;
339 
340 
341 		BYTE FrCustomMediaSeq[] = {0xC0,0x00, 0xF8, 0x30};
342 		err = thePrinter->Send ((const BYTE *)FrCustomMediaSeq, sizeof(FrCustomMediaSeq));
343 		ERRCHECK;
344 	}
345 	else
346 #endif
347 	{
348 		err = thePrinter->Send ((const BYTE*)FrPaperSizeSeq,sizeof(FrPaperSizeSeq));
349 		ERRCHECK;
350 	}
351 
352 	err = thePrinter->Send ((const BYTE *)FrBeginPageSeq, sizeof(FrBeginPageSeq));
353 	ERRCHECK;
354 
355 	bLastBand = FALSE;
356 
357     return err;
358 }
359 
EndPage()360 DRIVER_ERROR HeaderLJFastRaster::EndPage ()
361 {
362     DRIVER_ERROR err;
363 
364     // 0x44 - end page
365 	err = thePrinter->Send ((const BYTE*)FrEndPageSeq,sizeof(FrEndPageSeq));
366 	ERRCHECK;
367 
368     return err;
369 }
370 
EndJob()371 DRIVER_ERROR HeaderLJFastRaster::EndJob ()
372 {
373     DRIVER_ERROR    err = NO_ERROR;
374 
375 	err = thePrinter->Send((const BYTE*)FrCloseDataSourceSeq, sizeof(FrCloseDataSourceSeq));
376 	ERRCHECK;
377 
378 	err = thePrinter->Send((const BYTE*)FrEndSessionSeq, sizeof(FrEndSessionSeq));
379 	ERRCHECK;
380 
381 	err = thePrinter->Send((const BYTE*)ccpPJLExitSeq, strlen (ccpPJLExitSeq));
382 	ERRCHECK;
383 
384     return err;
385 }
386 
FormFeed()387 DRIVER_ERROR HeaderLJFastRaster::FormFeed ()
388 {
389 	DRIVER_ERROR    err = NO_ERROR;
390     LJFastRaster    *pFRPrinter = (LJFastRaster *) thePrinter;
391 
392 	bLastBand = TRUE;
393 
394 	err = EndPage ();
395 
396 	pFRPrinter->m_bStartPageNotSent = TRUE;
397 	return err;
398 }
399 
SendCAPy(unsigned int iAbsY)400 DRIVER_ERROR HeaderLJFastRaster::SendCAPy (unsigned int iAbsY)
401 {
402     return NO_ERROR;
403 }
404 
405 #define		FAST_RASTER_HEADERSIZE	25
406 
407 //** Faster Raster Path Header address values
408 
409 #define		BASE_ADDRESS					0
410 #define		PAGE_NUM_ADDRESS				1
411 #define		RESOLUTION_ADDRESS_HI			2
412 #define		RESOLUTION_ADDRESS_LO			3
413 #define		COMPRESSION_ADDRESS_HI			4
414 #define		COMPRESSION_ADDRESS_LO			5
415 #define		COLOR_PLANE_SPECIFIER_ADDRESS	6
416 #define		COMPRESSION_RATIO				7
417 #define		PRODUCT_ID						8
418 #define		IMAGE_SIZE_ADDRESS_HIWORD_HI	12
419 #define		IMAGE_SIZE_ADDRESS_HIWORD_LO	13
420 #define		IMAGE_SIZE_ADDRESS_LOWORD_HI	14
421 #define		IMAGE_SIZE_ADDRESS_LOWORD_LO	15
422 #define		IMAGE_WIDTH_ADDRESS_HI			16
423 #define		IMAGE_WIDTH_ADDRESS_LO			17
424 #define		IMAGE_HEIGTH_ADDRESS_HI			18
425 #define		IMAGE_HEIGTH_ADDRESS_LO			19
426 #define		ABS_X_ADDRESS_HI				20
427 #define		ABS_X_ADDRESS_LO				21
428 #define		ABS_Y_ADDRESS_HI				22
429 #define		ABS_Y_ADDRESS_LO				23
430 #define		BIT_DEPTH_ADDRESS				24
431 
432 #define eK 3
433 typedef enum
434 {
435 	eDelta32,
436 	eDeltaPlus = 24,
437 	eFX = 18,
438 	eRAW = 2
439 } CompressionMethod;
440 
441 #define		KILOBYTE 1024
442 #define		MAX_IMAGE 200*KILOBYTE
443 
Encapsulate(const RASTERDATA * InputRaster,BOOL bLastPlane)444 DRIVER_ERROR LJFastRaster::Encapsulate (const RASTERDATA* InputRaster, BOOL bLastPlane)
445 {
446     BYTE    res[64];
447     DRIVER_ERROR    err = NO_ERROR;
448 
449 	//** form FR header
450 	unsigned char	pucHeader[FAST_RASTER_HEADERSIZE];
451 	long lImageWidth = ((ModeDeltaPlus*)m_pCompressor)->inputsize;
452 	long lResolution = 600;
453 	long lBlockOffset = ((((ModeDeltaPlus*)m_pCompressor)->m_lPrinterRasterRow + 127) / 128) * 128 - 128;
454 	long lBitDepth = 1;
455 	long lBlockHeight = ((ModeDeltaPlus*)m_pCompressor)->m_lCurrBlockHeight;
456 
457 	WORD wTemp = LOWORD (lBlockOffset);
458 	BYTE byHIByte = 0;
459 	BYTE byLOByte = 0;
460 
461     memset (pucHeader, 0, FAST_RASTER_HEADERSIZE);
462 
463 	pucHeader[ABS_X_ADDRESS_HI] = 0;
464 	pucHeader[ABS_X_ADDRESS_LO] = 0;
465 	pucHeader[ABS_Y_ADDRESS_HI] = HIBYTE (wTemp);
466 	pucHeader[ABS_Y_ADDRESS_LO] = LOBYTE (wTemp);
467 
468 	pucHeader[BASE_ADDRESS] = 0;
469 	pucHeader[PAGE_NUM_ADDRESS] = 1;
470 
471 	wTemp = (WORD) (lResolution );
472 	byHIByte = HIBYTE (wTemp);
473 	byLOByte = LOBYTE (wTemp);
474 	pucHeader[RESOLUTION_ADDRESS_HI] = byHIByte;
475 	pucHeader[RESOLUTION_ADDRESS_LO] = byLOByte;
476 
477 	wTemp = ((ModeDeltaPlus*)m_pCompressor)->m_bCompressed ? (WORD)eDeltaPlus : (WORD)eRAW;
478 	byHIByte = HIBYTE (wTemp);
479 	byLOByte = LOBYTE (wTemp);
480 	pucHeader[COMPRESSION_ADDRESS_HI] = byHIByte;
481 	pucHeader[COMPRESSION_ADDRESS_LO] = byLOByte;
482 
483 	pucHeader[COLOR_PLANE_SPECIFIER_ADDRESS]	= (BYTE)eK;
484 	pucHeader[COMPRESSION_RATIO]				= (BYTE)ceil (((ModeDeltaPlus*)m_pCompressor)->m_fRatio);
485 	wTemp = HIWORD (InputRaster->rastersize[COLORTYPE_COLOR]);
486 	byHIByte = HIBYTE (wTemp);
487 	byLOByte = LOBYTE (wTemp);
488 	pucHeader[IMAGE_SIZE_ADDRESS_HIWORD_HI] = byHIByte;
489 	pucHeader[IMAGE_SIZE_ADDRESS_HIWORD_LO] = byLOByte;
490 
491 	wTemp = LOWORD (InputRaster->rastersize[COLORTYPE_COLOR]);
492 	byHIByte = HIBYTE (wTemp);
493 	byLOByte = LOBYTE (wTemp);
494 	pucHeader[IMAGE_SIZE_ADDRESS_LOWORD_HI] = byHIByte;
495 	pucHeader[IMAGE_SIZE_ADDRESS_LOWORD_LO] = byLOByte;
496 
497 	wTemp = LOWORD (lImageWidth*8);
498 	byHIByte = HIBYTE (wTemp);
499 	byLOByte = LOBYTE (wTemp);
500 
501 	pucHeader[IMAGE_WIDTH_ADDRESS_HI] = byHIByte;
502 	pucHeader[IMAGE_WIDTH_ADDRESS_LO] = byLOByte;
503 
504 	wTemp = LOWORD (lBlockHeight);
505 	byHIByte = HIBYTE (wTemp);
506 	byLOByte = LOBYTE (wTemp);
507 	pucHeader[IMAGE_HEIGTH_ADDRESS_HI] = byHIByte;
508 	pucHeader[IMAGE_HEIGTH_ADDRESS_LO] = byLOByte;
509 
510 	wTemp = LOWORD (lBitDepth);
511 	pucHeader[BIT_DEPTH_ADDRESS] = LOBYTE (wTemp);
512 
513     unsigned int   ulVUDataLength = (int)(InputRaster->rastersize[COLORTYPE_COLOR] + FAST_RASTER_HEADERSIZE);
514 
515 	BYTE FrEnterFRModeSeq[] = {0xC2, 0x06, 0x20, 0x70,0x68, 0xF8, 0x91, 0xC2};
516 	err = Send ((const BYTE *)FrEnterFRModeSeq, sizeof(FrEnterFRModeSeq));
517 	ERRCHECK;
518     res[0] = (BYTE) (ulVUDataLength & 0xFF);
519     res[1] = (BYTE) ((ulVUDataLength & 0x0000FF00) >> 8);
520     res[2] = (BYTE) ((ulVUDataLength & 0x00FF0000) >> 16);
521     res[3] = (BYTE) ((ulVUDataLength & 0xFF000000) >> 24);
522     res[4] = 0xF8;
523     res[5] = 0x92;
524     res[6] = 0x46;
525     err = Send (res, 7);
526 	ERRCHECK;
527 
528 	//** now embed raster data, header and all
529     err = Send (pucHeader, FAST_RASTER_HEADERSIZE);
530 	ERRCHECK;
531     err = Send (InputRaster->rasterdata[COLORTYPE_COLOR],
532 			    InputRaster->rastersize[COLORTYPE_COLOR]);
533     return err;
534 }
535 
SelectHeader(PrintContext * pc)536 Header* LJFastRaster::SelectHeader (PrintContext *pc)
537 {
538     phLJFastRaster = new HeaderLJFastRaster (this, pc);
539 	return phLJFastRaster;
540 }
541 
VerifyPenInfo()542 DRIVER_ERROR LJFastRaster::VerifyPenInfo()
543 {
544     ePen = BLACK_PEN;
545     return NO_ERROR;
546 }
547 
ParsePenInfo(PEN_TYPE & ePen,BOOL QueryPrinter)548 DRIVER_ERROR LJFastRaster::ParsePenInfo(PEN_TYPE& ePen, BOOL QueryPrinter)
549 {
550     ePen = BOTH_PENS;
551 
552     return NO_ERROR;
553 }
554 
CreateCompressor(unsigned int RasterSize)555 Compressor* LJFastRaster::CreateCompressor (unsigned int RasterSize)
556 {
557     m_pCompressor = new ModeDeltaPlus (pSS, this, RasterSize);
558 	return m_pCompressor;
559 }
560 
561 /*
562  *  Function name: ParseError
563  *
564  *  Owner: Darrell Walker
565  *
566  *  Purpose:  To determine what error state the printer is in.
567  *
568  *  Called by: Send()
569  *
570  *  Parameters on entry: status_reg is the contents of the centronics
571  *                      status register (at the time the error was
572  *                      detected)
573  *
574  *  Parameters on exit: unchanged
575  *
576  *  Return Values: The proper DISPLAY_STATUS to reflect the printer
577  *              error state.
578  *
579  */
ParseError(BYTE status_reg)580 DISPLAY_STATUS LJFastRaster::ParseError(BYTE status_reg)
581 {
582     DBG1("LJFastRaster: parsing error info\n");
583 
584     DRIVER_ERROR err = NO_ERROR;
585     BYTE    szReadBuff[256];
586     DWORD   iReadCount = 256;
587     DISPLAY_STATUS  eStatus = (DISPLAY_STATUS) status_reg;
588     char    *tmpStr;
589     int     iErrorCode;
590 
591     if (!IOMode.bDevID)
592         return eStatus;
593 
594     memset (szReadBuff, 0, 256);
595     err = pSS->FromDevice (szReadBuff, &iReadCount);
596     if (err == NO_ERROR && iReadCount == 0)
597         return eStatus;
598 
599     if (strstr ((char *) szReadBuff, "JOB"))
600     {
601         if (!(tmpStr = strstr ((char *) szReadBuff, "NAME")))
602             return DISPLAY_PRINTING;
603         tmpStr += 6;
604         while (*tmpStr < '0' || *tmpStr > '9')
605             tmpStr++;
606         sscanf (tmpStr, "%d", &iErrorCode);
607         if (iErrorCode != (long) (this))
608             return DISPLAY_PRINTING;
609     }
610 
611     if (strstr ((char *) szReadBuff, "END"))
612     {
613         return DISPLAY_PRINTING_COMPLETE;
614     }
615 
616 
617     if (strstr ((char *) szReadBuff, "CANCEL"))
618         return DISPLAY_PRINTING_CANCELED;
619 
620     if (!(tmpStr = strstr ((char *) szReadBuff, "CODE")))
621         return eStatus;
622 
623     tmpStr += 4;
624     while (*tmpStr < '0' || *tmpStr > '9')
625         tmpStr++;
626     sscanf (tmpStr, "%d", &iErrorCode);
627 
628     if (iErrorCode < 32000)
629         return DISPLAY_PRINTING;
630 
631     if (iErrorCode == 40010 || iErrorCode == 40020)
632         return DISPLAY_NO_PENS;     // Actually, out of toner
633 
634     if (iErrorCode == 40021)
635         return DISPLAY_TOP_COVER_OPEN;
636 
637     if ((iErrorCode / 100) == 419)
638         return DISPLAY_OUT_OF_PAPER;
639 
640     if ((iErrorCode / 1000) == 42 || iErrorCode == 40022)
641     {
642         DBG1("Paper Jammed\n");
643         return DISPLAY_PAPER_JAMMED;
644     }
645 
646     if (iErrorCode > 40049 && iErrorCode < 41000)
647     {
648         DBG1("IO trap\n");
649         return DISPLAY_ERROR_TRAP;
650     }
651 
652     if (iErrorCode == 40079)
653         return DISPLAY_OFFLINE;
654 
655     return DISPLAY_ERROR_TRAP;
656 }
657 
658 
659 //--------------------------------------------------------------------
660 // Function:    ModeDeltaPlus::ModeDeltaPlus
661 //
662 // Release:     [PROTO4_1]
663 //
664 // Description: Preferred ctor
665 //
666 // Input:        padMultiple - the fBufferDataLength returned from
667 //                             GetRow must be divisible by this value.
668 //
669 // Modifies:     fpBuffer
670 //
671 // Precond:      None
672 //
673 // Postcond:     None
674 //
675 // Returns:      None
676 //
677 // Created:            11/07/96 cal
678 // Last Modified:      5/020/01 DG
679 //--------------------------------------------------------------------
ModeDeltaPlus(SystemServices * pSys,Printer * pPrinter,unsigned int PlaneSize)680 ModeDeltaPlus::ModeDeltaPlus
681 (
682 	SystemServices* pSys,
683     Printer* pPrinter,
684     unsigned int PlaneSize
685 ) :
686     Compressor(pSys, PlaneSize, TRUE),
687     thePrinter(pPrinter),    // needed by Flush
688     pbyInputImageBuffer (NULL),
689     pbySeedRow (NULL)
690 {
691     if (constructor_error != NO_ERROR)  // if error in base constructor
692     {
693         return;
694     }
695 
696 	inputsize = PlaneSize / (MAXCOLORPLANES * MAXCOLORDEPTH * MAXCOLORROWS);
697     inputsize = ((inputsize + 7) / 8) * 8;
698 
699 	// allocate a 2X compression buffer..
700 	compressBuf = (BYTE*)pSS->AllocMem(2 * INDY_STRIP_HEIGHT * inputsize);
701 	if (compressBuf == NULL)
702     {
703 		constructor_error = ALLOCMEM_ERROR;
704     }
705 	memset (compressBuf, 0x00, 2 * INDY_STRIP_HEIGHT * inputsize);
706 
707 	pbyInputImageBuffer = (BYTE*)pSS->AllocMem(INDY_STRIP_HEIGHT * inputsize);
708 	if (pbyInputImageBuffer == NULL)
709 		constructor_error=ALLOCMEM_ERROR;
710 	memset(pbyInputImageBuffer, 0x00, INDY_STRIP_HEIGHT * inputsize);
711 
712     pbySeedRow = (HPUInt8*) pSS->AllocMem (inputsize * sizeof (HPUInt8));
713     if (pbySeedRow == NULL)
714     {
715         constructor_error = ALLOCMEM_ERROR;
716     }
717     memset (pbySeedRow, 0, inputsize * sizeof (HPUInt8));
718 
719 	m_lCurrCDRasterRow	= 0;
720 	//m_lPrinterRasterRow = (((LJFastRaster*)thePrinter)->phLJFastRaster)->thePrintContext->PrintableStartY() * 600;
721 
722 	m_lPrinterRasterRow = 0;
723 
724 	iRastersReady = 0;
725 
726 	m_bCompressed = FALSE;
727 	m_compressedsize = 0;
728 	m_fRatio = 0;
729 } // ModeDeltaPlus::ModeDeltaPlus
730 
731 
732 //--------------------------------------------------------------------
733 // Function:    ModeDeltaPlus::~ModeDeltaPlus
734 //
735 // Release:     [PROTO4_1]
736 //
737 // Description: Destructor.
738 //
739 // Input:       None
740 //
741 // Modifies:    fpBuffer - deletes the buffer
742 //              ?? - deletes other buffer(s)??
743 //
744 // Precond:     None
745 //
746 // Postcond:    None
747 //
748 // Returns:     None
749 //
750 // Created:            11/07/96 cal
751 // Last Modified:      5/020/01 DG
752 //--------------------------------------------------------------------
~ModeDeltaPlus()753 ModeDeltaPlus::~ModeDeltaPlus ()
754 {
755 	if (pbyInputImageBuffer)
756 	{
757 		pSS->FreeMem (pbyInputImageBuffer);
758 		pbyInputImageBuffer = NULL;
759 	}
760     if (pbySeedRow)
761     {
762         pSS->FreeMem (pbySeedRow);
763         pbySeedRow = NULL;
764     }
765 
766 } // ModeDeltaPlus::~ModeDeltaPlus
767 
768 /*
769  * The maximum width of a line, which is limited by the amount of hardware
770  * buffer space allocated to storing the seedrow.
771  */
772 #define ROW_LIMIT 7040
773 /*
774  * The maximum number of literals in a single command, not counting the first
775  * pixel.  This is limited by the hardware buffer used to store a literal
776  * string.  For real images, I expect a value of 64 would be a suitable
777  * minimum.  The minimum compression ratio will be bounded by this.  Note also
778  * that the software does not need any buffer for this, so there need be no
779  * limit at all on a purely software implementation.  For the sake of enabling
780  * a hardware implementation, I would strongly recommend leaving it in and set
781  * to some reasonable value (say 1023 or 255).
782  */
783 #define LITERAL_LIMIT 511
784 
785 /* These are set up this way to make it easy to change the predictions. */
786 #define LTEST_W            col > 0
787 #define LVAL_W(col)        cur_row[col-1]
788 #define LTEST_NW           col > 0
789 #define LVAL_NW(col)       seedrow[col-1]
790 #define LTEST_WW           col > 1
791 #define LVAL_WW(col)       cur_row[col-2]
792 #define LTEST_NWW          col > 1
793 #define LVAL_NWW(col)      seedrow[col-2]
794 #define LTEST_NE           (col+1) < row_width
795 #define LVAL_NE(col)       seedrow[col+1]
796 #define LTEST_NEWCOL       1
797 #define LVAL_NEWCOL(col)   new_color
798 #define LTEST_CACHE        1
799 #define LVAL_CACHE(col)    cache
800 
801 #define LOC1TEST      LTEST_NE
802 #define LOC1VAL(col)  LVAL_NE(col)
803 #define LOC2TEST      LTEST_NW
804 #define LOC2VAL(col)  LVAL_NW(col)
805 #define LOC3TEST      LTEST_NEWCOL
806 #define LOC3VAL(col)  LVAL_NEWCOL(col)
807 
808 
809 #define check(condition) if (!(condition)) return 0
810 
811 #define write_comp_byte(val)           \
812    check(outptr < pastoutmem);         \
813    *outptr++ = (HPUInt8) val;
814 
815 #define read_byte(val)                 \
816    check(inmem < pastinmem);           \
817    val = *inmem++;
818 
819 #define encode_count(count, over, mem)         \
820    if (count >= over)                          \
821    {                                           \
822       count -= over;                           \
823       if (count <= (uint32_t) 253)               \
824       {                                        \
825          check(mem < pastoutmem);              \
826          *mem++ = (HPUInt8) count;               \
827       }                                        \
828       else if (count <= (uint32_t) (254 + 255) ) \
829       {                                        \
830          check((mem+1) < pastoutmem);          \
831          check( count >= 254 );                \
832          check( (count - 254) <= 255 );        \
833          *mem++ = (HPUInt8) 0xFE;                \
834          *mem++ = (HPUInt8) (count - 254);       \
835       }                                        \
836       else                                     \
837       {                                        \
838          check((mem+2) < pastoutmem);          \
839          check( count >= 255 );                \
840          check( (count - 255) <= 65535 );      \
841          count -= 255;                         \
842          *mem++ = (HPUInt8) 0xFF;                \
843          *mem++ = (HPUInt8) (count >> 8);        \
844          *mem++ = (HPUInt8) (count & 0xFF);      \
845       }                                        \
846    }
847 #define decode_count(count, over)              \
848    if (count >= over)                          \
849    {                                           \
850       read_byte(inval);                        \
851       count += (uint32_t) inval;                 \
852       if (inval == (HPUInt8) 0xFE)               \
853       {                                        \
854          read_byte(inval);                     \
855          count += (uint32_t) inval;              \
856       }                                        \
857       else if (inval == (HPUInt8) 0xFF)          \
858       {                                        \
859          read_byte(inval);                     \
860          count += (((uint32_t) inval) << 8);     \
861          read_byte(inval);                     \
862          count += (uint32_t) inval;              \
863       }                                        \
864    }
865 
866 #define bytes_for_count(count, over) \
867   ( (count >= 255) ? 3 : (count >= over) ? 1 : 0 )
868 
869 
870 /* The number of bytes we should be greater than to call memset/memcpy */
871 #define memutil_thresh 15
872 
encode_header(HPUInt8 * outptr,const HPUInt8 * pastoutmem,uint32_t isrun,uint32_t location,uint32_t seedrow_count,uint32_t run_count,const HPUInt8 new_color)873 HPUInt8* ModeDeltaPlus::encode_header(HPUInt8* outptr, const HPUInt8* pastoutmem, uint32_t isrun, uint32_t location, uint32_t seedrow_count, uint32_t run_count, const HPUInt8 new_color)
874 {
875     uint32_t byte;
876 
877     check (location < 4);
878     check( (isrun == 0) || (isrun == 1) );
879 
880     /* encode "literal" in command byte */
881     byte = (isrun << 7) | (location << 5);
882 
883     /* write out number of seedrow bytes to copy */
884     if (seedrow_count > 2)
885         byte |= (0x03 << 3);
886     else
887         byte |= (seedrow_count << 3);
888 
889     if (run_count > 6)
890         byte |= 0x07;
891     else
892         byte |= run_count;
893 
894     /* write out command byte */
895     write_comp_byte(byte);
896 
897     /* macro to write count if it's 3 or more */
898     encode_count( seedrow_count, 3, outptr );
899 
900     /* if required, write out color of first pixel */
901     if (location == 0)
902     {
903         write_comp_byte( new_color );
904     }
905 
906     /* macro to write count if it's 7 or more */
907     encode_count( run_count, 7, outptr );
908 
909     return outptr;
910 }
911 
912 /******************************************************************************/
913 /*                                COMPRESSION                                 */
914 /******************************************************************************/
Compress(HPUInt8 * outmem,uint32_t * outlen,const HPUInt8 * inmem,const uint32_t row_width,const uint32_t inheight,uint32_t horz_ht_dist)915 BOOL ModeDeltaPlus::Compress (HPUInt8   *outmem,
916                               uint32_t  *outlen,
917                               const     HPUInt8     *inmem,
918                               const     uint32_t    row_width,
919                               const     uint32_t    inheight,
920                               uint32_t  horz_ht_dist)
921 {
922 	register    HPUInt8     *outptr = outmem;
923 	register    uint32_t    col;
924     const       HPUInt8     *seedrow;
925     uint32_t                seedrow_count = 0;
926     uint32_t                location = 0;
927     HPUInt8                 new_color = (HPUInt8) 0xFF;
928     const       HPUInt8     *cur_row;
929     uint32_t				row;
930     const       HPUInt8     *pastoutmem = outmem + *outlen;
931     uint32_t                do_word_copies;
932     /* Halftone distance must be 1-32 (but allow 0 == 1) */
933     if (horz_ht_dist > 32)
934     {
935         return FALSE;
936     }
937     if (horz_ht_dist < 1)
938     {
939        horz_ht_dist = 1;
940     }
941 
942     seedrow = pbySeedRow;
943     do_word_copies = ((row_width % 4) == 0);
944 
945     for (row = 0; row < inheight; row++)
946     {
947         cur_row = inmem + (row * row_width);
948 
949         col = 0;
950         while (col < row_width)
951         {
952             /* First look for seedrow copy */
953             seedrow_count = 0;
954             if (do_word_copies)
955             {
956                 /* Try a fast word-based search */
957                 while ( ((col & 3) != 0) &&
958                         (col < row_width) &&
959                         (cur_row[col] == seedrow[col]) )
960                 {
961                     seedrow_count++;
962                     col++;
963                 }
964                 if ( (col & 3) == 0)
965                 {
966                     while ( ((col+3) < row_width) &&
967                             *((const uint32_t*) (cur_row + col)) == *((const uint32_t*) (seedrow + col)) )
968                     {
969                         seedrow_count += 4;
970                         col += 4;
971                     }
972                 }
973             }
974             while ( (col < row_width) && (cur_row[col] == seedrow[col]) )
975             {
976                seedrow_count++;
977                col++;
978             }
979 
980             /* It is possible that we have hit the end of the line already. */
981             if (col == row_width)
982             {
983                 /* encode pure seed run as fake run */
984                 outptr = encode_header(outptr, pastoutmem, 1 /*run*/, 1 /*location*/, seedrow_count, 0 /*runcount*/, (HPUInt8) 0 /*color*/);
985                 /* exit the while loop for this row */
986                 break;
987             }
988             check(col < row_width);
989 
990 
991             /* determine the prediction for the current pixel */
992             if ( (LOC1TEST) && (cur_row[col] == LOC1VAL(col)) )
993                 location = 1;
994             else if ( (LOC2TEST) && (cur_row[col] == LOC2VAL(col)) )
995                 location = 2;
996             else if ( (LOC3TEST) && (cur_row[col] == LOC3VAL(col)) )
997                 location = 3;
998             else
999             {
1000                 location = 0;
1001                 new_color = cur_row[col];
1002             }
1003 
1004 
1005             /* Look for a run */
1006             if (
1007                  ((col+1) < row_width)
1008                  &&
1009                  ((col+1) >= horz_ht_dist)
1010                  &&
1011                  (cur_row[col+1-horz_ht_dist] == cur_row[col+1])
1012                )
1013             {
1014                 /* We found a run.  Determine the length. */
1015                 uint32_t run_count = 0;   /* Actually 2 */
1016                 col++;
1017                 while ( ((col+1) < row_width) && (cur_row[col+1-horz_ht_dist] == cur_row[col+1]) )
1018                 {
1019                    run_count++;
1020                    col++;
1021                 }
1022                 col++;
1023                 outptr = encode_header(outptr, pastoutmem, 1 /*run*/, location, seedrow_count, run_count, new_color);
1024             }
1025 
1026             else
1027 
1028             /* We didn't find a run.  Encode literal(s). */
1029             {
1030                 uint32_t replacement_count = 0;   /* Actually 1 */
1031                 const HPUInt8* byte_array = cur_row + col + 1;
1032                 uint32_t i;
1033                 col++;
1034                 /*
1035                  * The (col+1) in this test is used because there is no need to
1036                  * check for literal breaks if this is the last byte of the row.
1037                  * Instead we just tack it on to our literal count at the end.
1038                  */
1039                 while ( (col+1) < row_width )
1040                 {
1041                     /*
1042                      * All cases that will break with 1 unit saved.  This
1043                      * should be the best breaking spots, since we will always
1044                      * gain with the break, but never break for no gain.  This
1045                      * leads to longer strings which is good for decomp speed.
1046                      */
1047                     if (
1048                          /* Seedrow ... */
1049                          (
1050                            (cur_row[col] == seedrow[col])
1051                            &&
1052                            (
1053                              /* 2 seedrows */
1054                              (
1055                                (cur_row[col+1] == seedrow[col+1])
1056                              )
1057                              ||
1058                              /* seedrow and predict */
1059                              (
1060                                (cur_row[col+1] == LVAL_NW(col+1))
1061                                ||
1062                                (cur_row[col+1] == LVAL_NEWCOL(col+1))
1063                              )
1064                              ||
1065                              (
1066                                ((col+2) < row_width)
1067                                &&
1068                                (
1069                                  /* seedrow and run */
1070                                  (
1071                                    ((col + 2) >= horz_ht_dist) &&
1072                                    (cur_row[col+2-horz_ht_dist] == cur_row[col+2])
1073                                  )
1074                                  ||
1075                                  /* seedrow and northeast predict */
1076                                  (cur_row[col+1] == LVAL_NE(col+1))
1077                                )
1078                              )
1079                            )
1080                          )
1081                          ||
1082                          /* Run ... */
1083                          (
1084                            (cur_row[col] != seedrow[col])
1085                            &&
1086                            ((col + 1) >= horz_ht_dist)
1087                            &&
1088                            (cur_row[col+1-horz_ht_dist] == cur_row[col+1])
1089                            &&
1090                            (
1091                              /* Run of 3 or more */
1092                              (
1093                                ((col+2) < row_width)
1094                                &&
1095                                ((col + 2) >= horz_ht_dist)
1096                                &&
1097                                (cur_row[col+2-horz_ht_dist] == cur_row[col+2])
1098                              )
1099                              ||
1100                              /* Predict first unit of run */
1101                              (cur_row[col] == LVAL_NE(col))
1102                              ||
1103                              (cur_row[col] == LVAL_NW(col))
1104                              ||
1105                              (cur_row[col] == LVAL_NEWCOL(col))
1106                            )
1107                          )
1108                        )
1109                         break;
1110 
1111                     /* limited hardware buffer */
1112                     if (replacement_count >= LITERAL_LIMIT)
1113                         break;
1114 
1115                     /* add another literal to the list */
1116                     replacement_count++;
1117                     col++;
1118                 }
1119 
1120                 /* If almost at end of block, just extend the literal by one */
1121                 if ( (col+1) == row_width ) {
1122                    replacement_count++;
1123                    col++;
1124                 }
1125 
1126                 outptr = encode_header(outptr, pastoutmem, 0 /*not run*/, location, seedrow_count, replacement_count, new_color);
1127 
1128                 /* Copy bytes from the byte array.  If rc was 1, then we will
1129                  * have encoded a zero in the command byte, so nothing will be
1130                  * copied here (the 1 indicates the first pixel, which was
1131                  * written above or was predicted.  If rc is between 2 and 7,
1132                  * then a value between 1 and 6 will have been written in the
1133                  * command byte, and we will copy it directly.  If 8 or more,
1134                  * then we encode more counts, then finally copy all the values
1135                  * from byte_array.
1136                  */
1137 
1138                 if (replacement_count > 0)
1139                 {
1140                     /* Now insert rc bytes of data from byte_array */
1141                     if (replacement_count > memutil_thresh)
1142                     {
1143                         check( (outptr + replacement_count) <= pastoutmem );
1144                         memcpy(outptr, byte_array, (size_t) replacement_count);
1145                         outptr += replacement_count;
1146                     }
1147                     else
1148                     {
1149                         for (i = 0; i < replacement_count; i++)
1150                         {
1151                             write_comp_byte( byte_array[i] );
1152                         }
1153                     }
1154                 }
1155             }
1156 
1157         } /* end of column */
1158 
1159         /* save current row as next row's seed row */
1160         seedrow = cur_row;
1161 
1162     } /* end of row */
1163 
1164     check( outptr <= pastoutmem );
1165     if (outptr > pastoutmem)
1166     {
1167        /* We're in big trouble -- we wrote PAST the end of their memory! */
1168        *outlen = 0;
1169        return 0;
1170     }
1171 
1172     *outlen = (uint32_t) (outptr - outmem);
1173 
1174     return 1;
1175 } /* end of deltaplus_compress2 */
1176 
1177 
Process(RASTERDATA * input)1178 BOOL ModeDeltaPlus::Process
1179 (
1180     RASTERDATA* input
1181 )
1182 {
1183 	DRIVER_ERROR		err = NO_ERROR;
1184 
1185     if (input==NULL ||
1186 		(input->rasterdata[COLORTYPE_COLOR]==NULL && input->rasterdata[COLORTYPE_BLACK]==NULL))    // flushing pipeline
1187     {
1188         return FALSE;
1189     }
1190 	if (input->rasterdata[COLORTYPE_COLOR])
1191 	{
1192 		if (m_lCurrCDRasterRow < INDY_STRIP_HEIGHT )
1193 		{
1194 			//Copy the data to m_SourceBitmap
1195 			memcpy(pbyInputImageBuffer + m_lCurrCDRasterRow * inputsize, input->rasterdata[COLORTYPE_COLOR], input->rastersize[COLORTYPE_COLOR]);
1196 			m_lCurrCDRasterRow ++;
1197 		}
1198 		if (m_lCurrCDRasterRow == INDY_STRIP_HEIGHT || ((LJFastRaster*)thePrinter)->phLJFastRaster->IsLastBand())
1199 		{
1200 			if (((LJFastRaster*)thePrinter)->m_bStartPageNotSent)
1201 			{
1202 				err = (((LJFastRaster*)thePrinter)->phLJFastRaster)->StartPage();
1203 				((LJFastRaster*)thePrinter)->m_bStartPageNotSent = FALSE;
1204 						m_lPrinterRasterRow = 0;
1205 			}
1206 
1207 			m_compressedsize = 2 * inputsize * INDY_STRIP_HEIGHT;
1208             BOOL bRet = Compress (compressBuf,
1209                                   &m_compressedsize,
1210                                   pbyInputImageBuffer,
1211                                   inputsize,
1212                                   m_lCurrCDRasterRow,
1213                                   16
1214                                   );
1215 			if (!bRet)
1216 			{
1217 				memcpy (compressBuf, pbyInputImageBuffer, inputsize * INDY_STRIP_HEIGHT);
1218 				m_compressedsize = inputsize * INDY_STRIP_HEIGHT;
1219 			}
1220 			else
1221 			{
1222 				m_bCompressed = TRUE;
1223 				//m_fRatio = (float)m_compressedsize / (float)(inputsize * INDY_STRIP_HEIGHT);
1224 			}
1225 
1226 			memset(pbyInputImageBuffer, 0x00, inputsize * INDY_STRIP_HEIGHT);
1227 
1228 			m_lPrinterRasterRow += m_lCurrCDRasterRow;
1229 			m_lCurrBlockHeight = m_lCurrCDRasterRow;
1230 			m_lCurrCDRasterRow = 0;
1231 			iRastersReady = 1;
1232 
1233 			((LJFastRaster*)thePrinter)->phLJFastRaster->SetLastBand(FALSE);
1234 		}
1235 		else
1236 		{
1237 			return FALSE;
1238 		}
1239 	}
1240 	return TRUE;
1241 } //Process
1242 
NextOutputRaster(COLORTYPE color)1243 BYTE* ModeDeltaPlus::NextOutputRaster(COLORTYPE color)
1244 // since we return 1-for-1, just return result first call
1245 {
1246 	if (iRastersReady==0)
1247 		return (BYTE*)NULL;
1248 
1249 	if (color == COLORTYPE_BLACK)
1250 	{
1251 		return (BYTE*)NULL;
1252 	}
1253 	else
1254 	{
1255 		iRastersReady=0;
1256 		return compressBuf;
1257 	}
1258 }
1259 
GetOutputWidth(COLORTYPE color)1260 unsigned int ModeDeltaPlus::GetOutputWidth(COLORTYPE  color)
1261 {
1262 	if (color == COLORTYPE_COLOR)
1263 	{
1264 		return m_compressedsize;
1265 	}
1266 	else
1267 	{
1268 		return 0;
1269 	}
1270 } //GetOutputWidth
1271 
1272 APDK_END_NAMESPACE
1273 
1274 #endif  // defined APDK_LJFASTRASTER
1275