Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpijs / dj3320.cpp
1 /*****************************************************************************\
2   dj3320.cpp : Implimentation for the DJ3320 class
3
4   Copyright (c) 2001 - 2006, Hewlett-Packard Co.
5   All rights reserved.
6
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10   1. Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12   2. Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15   3. Neither the name of Hewlett-Packard nor the names of its
16      contributors may be used to endorse or promote products derived
17      from this software without specific prior written permission.
18
19   THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
22   NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24   TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \***************************************************************************/
30
31 #ifdef APDK_DJ3320
32
33 #include "header.h"
34 #include "io_defs.h"
35 #include "dj3320.h"
36 #include "resources.h"
37 #include "printerproxy.h"
38
39 APDK_BEGIN_NAMESPACE
40 extern BYTE* GetHT3x3_4();
41 extern BYTE* GetHT6x6_4_970();
42 APDK_END_NAMESPACE
43
44 APDK_BEGIN_NAMESPACE
45
46 extern uint32_t ulMapDJ3320_K_3x3x1[9 * 9 * 9];
47 extern uint32_t ulMapDJ3320_K_6x6x1[9 * 9 * 9];
48 extern uint32_t ulMapDJ3320_CMY_3x3x1[9 * 9 * 9];
49 extern uint32_t ulMapDJ3320_CMY_6x6x1[9 * 9 * 9];
50 extern uint32_t ulMapDJ3320_KCMY_3x3x1[9 * 9 * 9];
51 extern uint32_t ulMapDJ3320_KCMY_6x6x1[9 * 9 * 9];
52 extern uint32_t ulMapDJ970_Gossimer_Normal_KCMY[ 9 * 9 * 9 ];
53
54 extern uint32_t ulMapDJ3600_KCMY_6x6x1[9 * 9 * 9];
55 extern uint32_t ulMapDJ3600_ClMlxx_6x6x1[9 * 9 * 9];
56 extern uint32_t ulMapDJ3600_KCMY_6x6x2[9 * 9 * 9];
57 extern uint32_t ulMapDJ3600_ClMlxx_6x6x2[9 * 9 * 9];
58 extern uint32_t ulMapDJ3600_KCMY_3x3x1[9 * 9 * 9];
59 extern uint32_t ulMapDJ3600_ClMlxx_3x3x1[9 * 9 * 9];
60
61 extern void AsciiHexToBinary(BYTE* dest, char* src, int count);
62
63 #define NULL 0
64 //#define DBG1(str)
65 //#define DBG2(str, i) {}
66 //#define DBG3(str, i, j) {}
67
68 DJ3320::DJ3320 (SystemServices* pSS, BOOL proto)
69 : Printer(pSS,NUM_DJ6XX_FONTS,proto), m_dsCurrentStatus(DISPLAY_PRINTING)
70 {
71
72     pLDLEncap = NULL;
73     m_iBytesPerSwing = 2;
74     m_iLdlVersion = 1;
75     m_iColorPenResolution = 300;\r
76     m_iBlackPenResolution = 1200;\r
77     m_iNumBlackNozzles    = 400;
78
79     if (IOMode.bDevID)
80     {
81         bCheckForCancelButton = TRUE;
82         constructor_error = VerifyPenInfo ();
83         CERRCHECK;
84 //        pSS->GetVertAlignFromDevice();
85     }
86     else
87         ePen = BOTH_PENS;    // matches default mode
88     CMYMap = ulMapDJ3320_CMY_3x3x1;
89     InitPrintModes ();
90
91     if (pSendBuffer)
92     {
93         pSS->FreeMem (pSendBuffer);
94     }
95     pSendBuffer = pSS->AllocMem (iBuffSize);
96     CNEWCHECK (pSendBuffer);
97 }
98
99 void    DJ3320::InitPrintModes ()
100 {
101     if (ePen == BLACK_PEN || ePen == MDL_PEN)
102     {
103         pMode[GRAYMODE_INDEX]    = new DJ3320KDraftMode ();
104         pMode[DEFAULTMODE_INDEX] = new DJ3320GrayMode (ePen);
105         ModeCount = 2;
106     }
107     else if (ePen == BOTH_PENS)
108     {
109         pMode[GRAYMODE_INDEX]       = new DJ3320GrayMode (ePen);
110         pMode[DEFAULTMODE_INDEX]    = new DJ3320NormalMode (ePen);
111         pMode[SPECIALMODE_INDEX]    = new DJ3320PhotoMode ();
112         pMode[SPECIALMODE_INDEX+1]  = new DJ3320KDraftMode ();
113         pMode[SPECIALMODE_INDEX+2]  = new DJ3320DraftMode (ePen);
114         ModeCount = 5;
115     }
116         else if (ePen == MDL_BOTH)
117         {
118                 pMode[GRAYMODE_INDEX]       = new DJ3320GrayMode (ePen);
119         pMode[DEFAULTMODE_INDEX]    = new DJ3600MDLNormalMode ();
120         pMode[SPECIALMODE_INDEX]    = new DJ3320KDraftMode ();
121                 pMode[SPECIALMODE_INDEX+1]  = new DJ3600MDLDraftMode ();
122                 pMode[SPECIALMODE_INDEX+2]  = new DJ3600MDLPhotoMode ();
123         ModeCount = 5;
124         }
125     else
126     {
127         pMode[DEFAULTMODE_INDEX]    = new DJ3320NormalMode (ePen);
128         pMode[SPECIALMODE_INDEX]    = new DJ3320PhotoMode ();
129         pMode[GRAYMODE_INDEX]       = new DJ3320DraftMode (ePen);
130         ModeCount = 3;
131     }
132 }
133
134 DRIVER_ERROR DJ3320::SetPens (PEN_TYPE eNewPen)
135 {
136     if (eNewPen == ePen)
137     {
138         return NO_ERROR;
139     }
140     ASSERT (eNewPen <= MAX_PEN_TYPE);
141     if (eNewPen > MAX_PEN_TYPE)
142     {
143         return UNSUPPORTED_PEN;
144     }
145
146     for (int i = 0; i < (int) ModeCount; i++)
147     {
148         if (pMode[i])
149         {
150             delete pMode[i];
151             pMode[i] = NULL;
152         }
153     }
154     ePen = eNewPen;
155     InitPrintModes ();
156     AdjustResolution ();
157
158     return NO_ERROR;
159 } //SetPens
160
161 DJ3320::~DJ3320 ()
162 {
163    if (ePen == COLOR_PEN && pMode[GRAYMODE_INDEX])
164    {
165         delete pMode[GRAYMODE_INDEX];
166         pMode[GRAYMODE_INDEX] = NULL;
167     }
168     if (pLDLEncap)
169         delete pLDLEncap;
170     if (pSendBuffer)
171         pSS->FreeMem ((BYTE *) pSendBuffer);
172     pSendBuffer = NULL;
173 }
174
175 DJ3320GrayMode::DJ3320GrayMode (PEN_TYPE ePen) : PrintMode (ulMapDJ3320_K_6x6x1)
176 {
177         if (ePen == MDL_BOTH)
178         {
179                 cmap.ulMap2 = ulMapDJ3600_ClMlxx_6x6x1;
180         }
181
182     ColorDepth[K] = 1;
183     dyeCount = 1;
184     pmColor = GREY_K;
185     CompatiblePens[1] = BLACK_PEN;
186         CompatiblePens[2] = MDL_BOTH;
187         CompatiblePens[3] = MDL_PEN;
188
189     ResolutionX[0] = 600;
190     ResolutionY[0] = 600;
191
192     BaseResX = 600;
193     BaseResY = 600;
194
195     MixedRes = FALSE;
196     bFontCapable = FALSE;
197     Config.bCompress = FALSE;
198 }
199
200 DJ3320KDraftMode::DJ3320KDraftMode () : GrayMode (ulMapDJ3320_K_3x3x1)
201 {
202     bFontCapable = FALSE;
203     Config.bCompress = FALSE;
204     theQuality = qualityDraft;
205     pmQuality = QUALITY_DRAFT;
206         CompatiblePens[2] = MDL_BOTH;
207         CompatiblePens[3] = MDL_PEN;
208 }
209
210 DJ3320DraftMode::DJ3320DraftMode (PEN_TYPE ePen)
211 : PrintMode (ulMapDJ3320_KCMY_3x3x1)
212 {
213
214     if (ePen == COLOR_PEN)
215     {
216         CompatiblePens[1] = ePen;
217         cmap.ulMap1 = ulMapDJ3320_CMY_3x3x1;
218         dyeCount = 3;
219     }
220
221     for (int i = 0; i < 4; i++)
222     {
223         ColorDepth[i] = 1;
224
225         ResolutionX[i] = 300;
226         ResolutionY[i] = 300;
227     }
228     MixedRes = FALSE;
229     BaseResX = 300;
230     BaseResY = 300;
231     bFontCapable = FALSE;
232     pmQuality = QUALITY_DRAFT;
233     Config.bCompress = FALSE;
234
235 //    strcpy(ModeName, "Draft");
236 }
237
238 DJ3320NormalMode::DJ3320NormalMode (PEN_TYPE ePen)
239 : PrintMode (ulMapDJ3320_KCMY_6x6x1)
240 {
241
242     if (ePen == COLOR_PEN)
243     {
244         CompatiblePens[1] = ePen;
245         cmap.ulMap1 = ulMapDJ3320_CMY_6x6x1;
246         dyeCount = 3;
247     }
248
249     for (int i = 0; i < 4; i++)
250     {
251         ColorDepth[i] = 1;
252
253         ResolutionX[i] = 600;
254         ResolutionY[i] = 600;
255     }
256
257     BaseResX = 600;
258     BaseResY = 600;
259     MixedRes = FALSE;
260
261     bFontCapable = FALSE;
262     Config.bCompress = FALSE;
263
264 //    strcpy(ModeName, "Normal");
265 }
266
267 DJ3320PhotoMode::DJ3320PhotoMode ()
268 : PrintMode (ulMapDJ970_Gossimer_Normal_KCMY)
269 {
270
271     for (int i = 0; i < 4; i++)
272     {
273         ColorDepth[i] = 2;
274
275         ResolutionX[i] = 600;
276         ResolutionY[i] = 600;
277     }
278     ColorDepth[0] = 1;
279     CompatiblePens[1] = COLOR_PEN;
280
281     BaseResX = 600;
282     BaseResY = 600;
283     MixedRes = FALSE;
284
285     ColorFEDTable = GetHT6x6_4_970 ();
286
287     bFontCapable = FALSE;
288
289     pmQuality = QUALITY_BEST;
290     pmMediaType = MEDIA_PHOTO;
291
292     medium = mediaGlossy;
293     theQuality = qualityPresentation;
294
295     Config.bCompress = FALSE;
296 }
297
298
299 //
300 // Plain Normal Print Mode for Photo and Color Pen
301 //
302 DJ3600MDLNormalMode::DJ3600MDLNormalMode()
303 : PrintMode( ulMapDJ3600_KCMY_6x6x1, ulMapDJ3600_ClMlxx_6x6x1 )
304 {
305         dyeCount=6;
306         CompatiblePens[0] = MDL_BOTH;
307
308     for (int i = 0; i < 6; i++)
309     {
310         ColorDepth[i] = 1;
311
312         ResolutionX[i] = 600;
313         ResolutionY[i] = 600;
314     }
315
316     BaseResX = 600;
317     BaseResY = 600;
318     MixedRes = FALSE;
319
320     bFontCapable = FALSE;
321     Config.bCompress = FALSE;
322 }
323
324 //
325 // Photo Best Print Mode for Photo and Color Pen
326 //
327 DJ3600MDLPhotoMode::DJ3600MDLPhotoMode()
328 : PrintMode( ulMapDJ3600_KCMY_6x6x2, ulMapDJ3600_ClMlxx_6x6x2 )
329 {
330         dyeCount=6;
331         CompatiblePens[0] = MDL_BOTH;
332
333     for (int i = 0; i < 6; i++)
334     {
335         ColorDepth[i] = 2;
336
337         ResolutionX[i] = 600;
338         ResolutionY[i] = 600;
339     }
340
341     BaseResX = 600;
342     BaseResY = 600;
343     MixedRes = FALSE;
344
345
346     ColorFEDTable = (BYTE*) HT600x6004level3600_open;
347
348     bFontCapable = FALSE;
349
350     pmQuality = QUALITY_BEST;
351     pmMediaType = MEDIA_PHOTO;
352
353     medium = mediaGlossy;
354     theQuality = qualityPresentation;
355     Config.bCompress = FALSE;
356 }
357
358 //
359 // Draft Mode for Photo and Color Pen
360 //
361 DJ3600MDLDraftMode::DJ3600MDLDraftMode()
362 : PrintMode( ulMapDJ3600_KCMY_3x3x1, ulMapDJ3600_ClMlxx_3x3x1 )
363 {
364         dyeCount=6;
365         CompatiblePens[0] = MDL_BOTH;
366
367     for (int i = 0; i < 6; i++)
368     {
369         ColorDepth[i] = 1;
370
371         ResolutionX[i] = 300;
372         ResolutionY[i] = 300;
373     }
374
375     BaseResX = 300;
376     BaseResY = 300;
377     MixedRes = FALSE;
378
379     bFontCapable = FALSE;
380         pmQuality = QUALITY_DRAFT;
381     Config.bCompress = FALSE;
382 }
383
384 DRIVER_ERROR DJ3320::Encapsulate (const RASTERDATA *pRasterData, BOOL bLastPlane)
385 {
386     return pLDLEncap->Encapsulate (pRasterData->rasterdata[COLORTYPE_COLOR], pRasterData->rastersize[COLORTYPE_COLOR], bLastPlane);
387 }
388
389 Header* DJ3320::SelectHeader(PrintContext* pc)
390 {
391     pLDLEncap = new LDLEncap (this, pSS, pc);
392     if (pLDLEncap)
393         pLDLEncap->AllocateSwathBuffer ((pc->OutputPixelsPerRow ()) / 8 + 2);
394     if (pLDLEncap->constructor_error != NO_ERROR)
395         return NULL;
396
397     return new Header3320 (this,pc);
398 }
399
400 /*
401  *    Author: Don Castrapel
402  */
403
404 DISPLAY_STATUS DJ3320::ParseError (BYTE byStatusReg)
405 {
406     DRIVER_ERROR err = NO_ERROR;
407     BYTE byDevIDBuffer[DevIDBuffSize];
408     char *pcStr = NULL;
409     BYTE byStatus1, byStatus2;
410
411     memset(byDevIDBuffer, 0, sizeof(byDevIDBuffer));
412     byStatus1 = byStatus2 = 0;
413
414     if (IOMode.bDevID)
415     {
416         // If a bi-di cable was plugged in and everything was OK, let's see if it's still
417         // plugged in and everything is OK
418         err = pSS->GetDeviceID (byDevIDBuffer, DevIDBuffSize, TRUE);
419         if (err)
420         {
421             // job was bi-di but now something's messed up, probably cable unplugged
422             m_dsCurrentStatus = DISPLAY_COMM_PROBLEM;
423             return DISPLAY_COMM_PROBLEM;
424         }
425     }
426
427     if (IOMode.bStatus)
428     {
429         if(pLDLEncap->bNewStatus)
430         {
431             pLDLEncap->bNewStatus = FALSE;
432
433             // First 10 bytes of m_pbyReadBuff are packet header.  Status query from printer has $S:
434             if ((pcStr = (char *) strstr((const char*)pLDLEncap->byStatusBuff + 10, "$S:")) == NULL)
435             {
436                 m_dsCurrentStatus = DISPLAY_COMM_PROBLEM;
437                 return DISPLAY_COMM_PROBLEM;
438             }
439
440             // Point to first byte of Feature State.  Skip 3 bytes for "$S:", 2 for version
441             pcStr += 5;
442             byStatus1 = *pcStr;
443
444             if (byStatus1 == '9')
445             {
446                 iTotal_SLOW_POLL_Count = 0;
447                 m_dsCurrentStatus = DISPLAY_TOP_COVER_OPEN;
448                 return DISPLAY_TOP_COVER_OPEN;
449             }
450
451             // Point to Printer State.  Skip 14-byte Feature State
452             pcStr += 14;
453             byStatus1 = *pcStr++;
454             byStatus2 = *pcStr++;
455
456             // In any of the cases where we know what's wrong, reset the slow poll count, which we're
457             // using as a "we know what's going on" variable, to 0 since we do know what's going on
458             if ((byStatus1 == '0') && (byStatus2 == '5'))
459             {
460                 // 05 = CNCL state
461                 iTotal_SLOW_POLL_Count = 0;
462                 m_dsCurrentStatus = DISPLAY_PRINTING_CANCELED;
463                 return DISPLAY_PRINTING_CANCELED;
464             }
465             if ((byStatus1 == '0') && (byStatus2 == '9'))
466             {
467                 // 09 = OOP state
468                 iTotal_SLOW_POLL_Count = 0;
469                 m_dsCurrentStatus = DISPLAY_OUT_OF_PAPER_NEED_CONTINUE;
470                 return DISPLAY_OUT_OF_PAPER_NEED_CONTINUE;
471             }
472             if ((byStatus1 == '0') && (byStatus2 == 'E'))
473             {
474                 // 0E = Paper jam
475                 iTotal_SLOW_POLL_Count = 0;
476                 m_dsCurrentStatus = DISPLAY_ERROR_TRAP;
477                 return DISPLAY_ERROR_TRAP;
478             }
479             if ((byStatus1 == '0') && (byStatus2 == 'F'))
480             {
481                 // 0F = Carriage stall
482                 iTotal_SLOW_POLL_Count = 0;
483                 m_dsCurrentStatus = DISPLAY_ERROR_TRAP;
484                 return DISPLAY_ERROR_TRAP;
485             }
486             if ((byStatus1 == '1') && (byStatus2 == '0'))
487             {
488                 // 10 = Paper stall
489                 iTotal_SLOW_POLL_Count = 0;
490                 m_dsCurrentStatus = DISPLAY_ERROR_TRAP;
491                 return DISPLAY_ERROR_TRAP;
492             }
493
494             // No problem detectable from status string.  Set default condition
495             m_dsCurrentStatus = DISPLAY_PRINTING;
496         }
497
498         // VerifyPenInfo will handle prompting the user if this is a problem
499         err = VerifyPenInfo();
500         if(err)
501             // VerifyPenInfo returned an error, which can only happen when ToDevice
502             // or GetDeviceID returns an error. Either way, it's BAD_DEVICE_ID or
503             // IO_ERROR, both unrecoverable.  This is probably due to the printer
504             // being turned off during printing
505             return DISPLAY_COMM_PROBLEM;
506     }
507
508     // Don't know what the problem is.  Increment wait count.  i_Total_SLOW_POLL_Count
509     // really has no meaning for the DJ3320, but since it's a printer class variable
510     // and it's not used for the DJ3320 we'll use it here rather than create another
511     // printer class variable
512     iTotal_SLOW_POLL_Count++;
513
514     // If we've exceeded our wait time and we still don't know what's wrong, return
515     // a communication problem
516     if(iTotal_SLOW_POLL_Count >= ERROR_WAIT)
517         return DISPLAY_BUSY;
518     else
519         return m_dsCurrentStatus;
520 }
521
522 /*
523  *    Author: Don Castrapel
524  */
525
526 DRIVER_ERROR DJ3320::Send (const BYTE* pWriteBuff, DWORD dwWriteCount)
527 {
528     DRIVER_ERROR    err = NO_ERROR;
529     DISPLAY_STATUS  eDisplayStatus = DISPLAY_PRINTING;
530     DWORD           dwResidual = 0;
531     DWORD           dwPrevResidual = 0;
532     const BYTE      *pWritePos = NULL;
533     BYTE            byPacketType = 0;
534     BYTE            byCommandNumber = 0;
535     BYTE            byCommandNumberOriginal = 0;
536     BYTE            byCreditWaitCount = 0;
537     BYTE            byCreditWaitCountOriginal = 0;
538     BYTE            byIOWaitCount = 0;
539     BOOL            bUpdateState = FALSE;
540     BOOL            bCreditForCommand = FALSE;
541     BOOL            bFlush = FALSE;
542     BOOL            bOriginalRequest = TRUE;
543
544     // DJ3400 doesn't use a staus reg, but we need one for the call to ParseError
545     BYTE            byStatusReg = 0;
546
547     // Buffering variables
548     DWORD           BytesToWrite = dwWriteCount;
549     DWORD           BytesToWriteOriginal = dwWriteCount;
550     const BYTE      *pWriteBuffOriginal = pWriteBuff;
551     const BYTE      *pBuffer = pWriteBuff;
552     DWORD           dwWriteCountOriginal = dwWriteCount;
553     DWORD           dwSendSize = dwWriteCount;
554
555     // Retry, query, and cancel variables
556     BOOL            bPrinterCancelButton = FALSE;
557     BOOL            bCanceling = FALSE;
558     BOOL            bCanceled = FALSE;
559
560 ////////////////////////////////////////////////////////////////
561 #ifdef NULL_IO
562     // test imaging speed independent of printer I/O, will not
563     // send any data to the device
564     return NO_ERROR;
565 #endif
566 ////////////////////////////////////////////////////////////////
567
568     if (!IOMode.bDevID)
569     {
570         return pSS->ToDevice (pWriteBuff, &dwSendSize);
571     }
572
573     if (ErrorTerminationState)
574     {
575         // Don't try any more I/O if we previously terminated in an error state
576         return JOB_CANCELED;
577     }
578
579     // If EndJob is TRUE we don't want to return.  The Job destructor is the only place that sets this
580     // boolean and we have to flush the buffer if EndJob is TRUE.
581     if (!EndJob)
582     {
583         if (dwWriteCount == 0)
584             // Don't bother processing an empty Send call
585             return NO_ERROR;
586
587         // Get Packet Type.  If Packet Type is a command, buffer it if buffering is turned on.  If it's
588         // a different Packet Type, send it directly to the printer
589         byPacketType = pWriteBuff[PACKET_TYPE_BYTE];
590
591         // Get Command Number if packet is a command.  If it is then we need to check for credit
592         // before we send the command
593         if(!byPacketType)
594         {
595             byCommandNumber = pWriteBuff[COMMAND_NUMBER_BYTE];
596             byCommandNumberOriginal = pWriteBuff[COMMAND_NUMBER_BYTE];
597         }
598     }
599     else
600     {
601         // Just flush whatever is in the buffer
602         bFlush = TRUE;
603     }
604
605     do
606     {
607         // If it's a command, check to see if we have credit for it.  If it's a special packet type,
608         // we'll just send it directly to the printer
609         if(!bCreditForCommand)
610         {
611             // Could be first time through do loop or could have not had credit and had to check.  We'll
612             // always get here since we don't change bCreditForCommand until here.
613             if (!byPacketType)
614             {
615                 // Check to see if we have credit for this command
616                 if (pLDLEncap->piCreditCount[byCommandNumber] > 0)
617                 {
618                     pLDLEncap->piCreditCount[byCommandNumber]--;
619                     bCreditForCommand = TRUE;
620                     byCreditWaitCount = 0;
621                 }
622                 else
623                 {
624                     byCreditWaitCount++;
625
626                     bUpdateState = pLDLEncap->UpdateState (FALSE);
627                     if(bUpdateState)
628                     {
629                         pSS->BusyWait(0);
630                         // Rechecking here will save us a trip through the do loop
631                         if (pLDLEncap->piCreditCount[byCommandNumber] > 0)
632                         {
633                             pLDLEncap->piCreditCount[byCommandNumber]--;
634                             bCreditForCommand = TRUE;
635                             byCreditWaitCount = 0;
636                         }
637                     }
638                 }
639             }
640             else
641             {
642                 // Special packet types get a free pass
643                 bCreditForCommand = TRUE;
644             }
645         } // if(!bCreditForCommand)
646
647         // If we don't have credit for the current command we don't want to put it in the
648         // buffer.  If, however, we have exceeded our credit wait limit and we need to check
649         // for an error, we have to flush what's in our buffer
650         if (bCreditForCommand || bFlush)
651         {
652             if (bCreditForCommand)
653             {
654                 // We should bypass the buffering for a large Send, but don't lose what may
655                 // already be buffered
656                 if ((BytesToWrite >= (DWORD) iBuffSize) && (iCurrBuffSize == 0))
657                 {
658                     pBuffer = pWriteBuff + (dwWriteCount - BytesToWrite);
659                     dwSendSize = BytesToWrite;
660                     BytesToWrite = 0;  // This is checked for at the end of the outer loop
661                 }
662                 else // We will buffer this data
663                 {
664                     // If it'll fit then just copy everything to the buffer
665                     if (BytesToWrite <= (DWORD) iBuffSize - iCurrBuffSize)
666                     {
667                         memcpy ((void*) (pSendBuffer + iCurrBuffSize),
668                                 (void*) (pWriteBuff + (dwWriteCount - BytesToWrite)),
669                                 BytesToWrite);
670                         iCurrBuffSize += BytesToWrite;
671                         BytesToWrite = 0;
672                     }
673                     else // Copy what we can into the buffer, we'll get the rest later
674                     {
675                         memcpy ((void*) (pSendBuffer + iCurrBuffSize),
676                                 (void*) (pWriteBuff + (dwWriteCount - BytesToWrite)),
677                                 iBuffSize - iCurrBuffSize);
678                         BytesToWrite -= (iBuffSize - iCurrBuffSize);
679                         iCurrBuffSize = iBuffSize;
680                     }
681                 }
682
683                 // If this wasn't the original request, like a query, continue, prepare to
684                 // cancel, or cancel command, flush the buffer immediately
685                 if(!bOriginalRequest)
686                 {
687                     bFlush = TRUE;
688                 }
689             } // if (bCreditForCommand)
690
691             // If the buffer is now full (ready-to-send) or if we're at the end of the job, or
692             // if the Packet Type is not a command then send what we have in the buffer.
693             // otherwise just break (the buffer isn't ready to send)
694             if ((EndJob == FALSE) && (iCurrBuffSize != iBuffSize)  && (!byPacketType) && (!bFlush) )
695             {
696                 // We're not ready to send yet.  Break out of do loop
697                 break;
698             }
699             else // Send this buffered data
700             {
701                 if (bFlush)
702                 {
703                     bFlush = FALSE;
704                 }
705                 pBuffer = pSendBuffer;
706                 dwSendSize = iCurrBuffSize;
707             }
708
709             // Initialize our 'residual' to the full send size
710             dwResidual = dwSendSize;
711
712             // Code to check to see if user has pressed cancel button.  DJ3320 front panel button, if
713             // pressed during normal printing, will initiate a cancel in the printer.  This will cause the
714             // printer to just throw away data but not notify the host.  We have to do that here if we
715             // detect a cancel
716             if(bCheckForCancelButton && (ulBytesSentSinceCancelCheck >= CANCEL_BUTTON_CHECK_THRESHOLD))
717             {
718                 ulBytesSentSinceCancelCheck = 0;
719
720                 if(ParseError(byStatusReg) == DISPLAY_PRINTING_CANCELED)
721                     bPrinterCancelButton = TRUE;
722             }
723
724             // If we have nothing to send, we need to bail to avoid spurious dialogs
725             // at the end of the ::send function.  I'd prefer a solution where we don't
726             // bail from a while loop but in practice this shouldn't have any ill effects.
727             if (dwResidual <= 0)
728             {
729                 return NO_ERROR;
730             }
731
732             // While still data to send in this request
733             while (dwResidual > 0)
734             {
735                 // WritePort overwrites request count, need to save
736                 dwPrevResidual = dwResidual;
737
738                 pWritePos = (const BYTE *) &(pBuffer[dwSendSize - dwResidual]);
739                 err = pSS->ToDevice (pWritePos, &dwResidual);
740
741                 if(err)
742                 {
743                     ErrorTerminationState = TRUE;
744                     return err;
745                 }
746
747                 // No more data to send this time
748                 if (dwResidual == 0)
749                 {
750                     // For USB printer class drivers that have buffering we need to flush the buffer.
751                     // If we are sending a special packet type and can't wait for a full buffer we have
752                     // to flush
753                     err = pSS->FlushIO ();
754                     if (err)
755                     {
756                         ErrorTerminationState = TRUE;
757                         return err;
758                     }
759                     // We successfully sent the entire non-original request, so reset to original
760                     // request
761                     if(!bOriginalRequest && !bCanceled)
762                     {
763                         pWriteBuff = pWriteBuffOriginal;
764                         dwWriteCount = dwWriteCountOriginal;
765                         BytesToWrite = BytesToWriteOriginal;
766                         byCommandNumber = byCommandNumberOriginal;
767                         bOriginalRequest = TRUE;
768                         bCreditForCommand = FALSE;
769                         byCreditWaitCount = byCreditWaitCountOriginal;
770                         // We have to give the printer some time to update its status and send us a
771                         // new status packet
772                         pSS->BusyWait(500);
773                     }
774                     else
775                     {
776                         if(bOriginalRequest)
777                         {
778                             byIOWaitCount = 0;
779                         }
780
781                         iTotal_SLOW_POLL_Count = 0;
782                     }
783
784                     break; // Out of while loop
785                 }
786                 else
787                 {
788                     if (dwPrevResidual == dwResidual)
789                     {
790                         // The I/O didn't take any data, increment count
791                         byIOWaitCount++;
792                     }
793                     else
794                     {
795                         // The I/O took some data, although not the full request
796                         if(bOriginalRequest)
797                             byIOWaitCount = 0;
798                     }
799                 }
800
801                 // If I/O hasn't finished after our timeout limit, we have to bail.
802                 if (byIOWaitCount >= IO_WAIT)
803                 {
804                     ErrorTerminationState = TRUE;
805                     pSS->DisplayPrinterStatus (DISPLAY_COMM_PROBLEM);
806                     return IO_ERROR;
807                 }
808
809                 // Check for user cancel each time through loop
810                 if (pSS->BusyWait ((DWORD)0) == JOB_CANCELED)
811                 {
812                     pSS->DisplayPrinterStatus (DISPLAY_PRINTING_CANCELED);
813                 }
814
815             } // while (residual > 0)
816
817             iCurrBuffSize = 0;
818
819         } // if(bCreditForCommand || bFlush)
820         else
821         {
822             // If we can't get credit and we've exceeded our wait limit, check for an error
823             if (byCreditWaitCount >= CREDIT_WAIT)
824             {
825                 if(!bOriginalRequest)
826                 {
827                     // Something is wrong but we don't know what it is and we can't get credit
828                     // to Query, Continue, Prepare to Cancel, or Cancel, so we have to bail
829                     ErrorTerminationState = TRUE;
830                     return JOB_CANCELED;
831                 }
832                 // Flush our internal buffer so that we can send command such as query or continue
833                 if (iCurrBuffSize)
834                 {
835                     bFlush = TRUE;
836                 }
837                 else
838                 {
839                     // See if we can find out what's wrong
840                     eDisplayStatus = ParseError(byStatusReg);
841
842                     // For recoverable cases such as out of paper or top cover open, we just want to
843                     // display the error and break.  For non-recoverable cases we'll wait for the
844                     // user to cancel the job and return.
845
846                     // If the user terminated in an error state we have to send the CancelJob,
847                     // unless the error state is a condition that would prevent a paper eject, such
848                     // as paper jam or error trap.  In those cases we'll just return, since the
849                     // user has to power cycle the printer before he can continue
850                     switch (eDisplayStatus)
851                     {
852                         case DISPLAY_PRINTING_CANCELED:
853                             // User canceled in an error condition, break from here and let check
854                             // for cancel at end of do loop send Cancel Job to printer
855                             pSS->DisplayPrinterStatus (eDisplayStatus);
856                             ErrorTerminationState = TRUE;
857
858                             break;
859
860                         case DISPLAY_ERROR_TRAP:
861                         case DISPLAY_COMM_PROBLEM:
862                             // These are unrecoverable cases.  Don't let any more of this job be sent
863                             // to the printer.  We can't even eject the page at the end of the job
864
865                             ErrorTerminationState = TRUE;
866                             pSS->DisplayPrinterStatus (eDisplayStatus);
867
868                             // Wait for user to cancel the job, otherwise they might miss the
869                             // error message
870                             while (pSS->BusyWait ((DWORD) 500) != JOB_CANCELED)
871                             {
872                                 // nothing....
873                                 ;
874                             }
875
876                             return IO_ERROR;
877
878                         case DISPLAY_TOP_COVER_OPEN:
879                             pSS->DisplayPrinterStatus(DISPLAY_TOP_COVER_OPEN);
880
881                             err = NO_ERROR;
882
883                             // Wait for top cover to close or user to cancel
884                             while(eDisplayStatus == DISPLAY_TOP_COVER_OPEN && !err)
885                             {
886                                 err = pSS->BusyWait((DWORD)500);
887                                 if(err == JOB_CANCELED)
888                                 {
889                                     ErrorTerminationState = TRUE;
890                                 }
891
892                                 if(!err)
893                                 {
894                                     bUpdateState = pLDLEncap->UpdateState(FALSE);
895                                     if(bUpdateState)
896                                     {
897                                         eDisplayStatus = ParseError(byStatusReg);
898
899                                         // Need to check for cancel here, because we could miss it if the
900                                         // user presses cancel button then lifts lid or something
901                                         if(eDisplayStatus == DISPLAY_PRINTING_CANCELED)
902                                         {
903                                             ErrorTerminationState = TRUE;
904                                             bPrinterCancelButton = TRUE;
905                                         }
906                                     }
907                                 }
908                             } // while(eDisplayStatus == DISPLAY_TOP_COVER_OPEN && !err)
909
910                             if(!err && !bPrinterCancelButton)
911                             {
912                                 pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
913
914                                 // Give the printer some time to come back online
915                                 if(pSS->BusyWait((DWORD)1000) == JOB_CANCELED)
916                                 {
917                                     ErrorTerminationState = TRUE;
918                                 }
919                             }
920
921                             break;
922
923                         case DISPLAY_OUT_OF_PAPER_NEED_CONTINUE:
924                             pSS->DisplayPrinterStatus (DISPLAY_OUT_OF_PAPER_NEED_CONTINUE);
925
926                             err = NO_ERROR;
927
928                             // Wait for user to add more paper and press resume button on printer or
929                             // select CONTINUE button from host's error dialog
930                             while(eDisplayStatus == DISPLAY_OUT_OF_PAPER_NEED_CONTINUE && !err)
931                             {
932                                 err = pSS->BusyWait((DWORD)500);
933
934                                 if (err == JOB_CANCELED)
935                                 {
936                                     ErrorTerminationState = TRUE;
937                                 }
938                                 else if(err == CONTINUE_FROM_BLOCK)
939                                 {
940                                     // Setup CONTINUE command
941                                     pWriteBuff = byContinue;
942                                     dwWriteCount = sizeof(byContinue);
943                                     BytesToWrite = sizeof(byContinue);
944                                     byCommandNumber = COMMAND_CONTINUE;
945                                     bOriginalRequest = FALSE;
946                                     bCreditForCommand = FALSE;
947                                     byCreditWaitCountOriginal = byCreditWaitCount;
948                                     byCreditWaitCount = 0;
949                                 }
950                                 else
951                                 {
952                                     bUpdateState = pLDLEncap->UpdateState(FALSE);
953                                     if(bUpdateState)
954                                     {
955                                         eDisplayStatus = ParseError(byStatusReg);
956
957                                         // Need to check for cancel here, because we could miss it if the
958                                         // user presses cancel button then lifts lid or something
959                                         if(eDisplayStatus == DISPLAY_PRINTING_CANCELED)
960                                         {
961                                             ErrorTerminationState = TRUE;
962                                             bPrinterCancelButton = TRUE;
963                                         }
964                                     }
965                                 }
966                             } // while(eDisplayStatus == DISPLAY_OUT_OF_PAPER_NEED_CONTINUE && !err)
967
968                             if(!err && !bPrinterCancelButton)
969                             {
970                                 pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
971                             }
972
973                             break;
974
975                         case DISPLAY_BUSY:
976                             pSS->DisplayPrinterStatus(DISPLAY_BUSY);
977
978                             if (pSS->BusyWait ((DWORD) 5000) == JOB_CANCELED)
979                             {
980                                 ErrorTerminationState = TRUE;
981                             }
982
983                             break;
984
985                         // Other cases need no special handling, display the error and try to continue
986                         default:
987                             pSS->DisplayPrinterStatus (eDisplayStatus);
988
989                             if (pSS->BusyWait ((DWORD) 500) == JOB_CANCELED)
990                             {
991                                 ErrorTerminationState = TRUE;
992                             }
993
994                             break;
995                     } // switch(eDisplayStatus)
996                 } // else(iCurrBuffSize)
997             } // if(byCreditWaitCount >= CREDIT_WAIT)
998         } // else(bCreditForCommand || bFlush)
999
1000         if (pSS->BusyWait ((DWORD)0) == JOB_CANCELED || bPrinterCancelButton)
1001         {
1002             pSS->DisplayPrinterStatus(DISPLAY_PRINTING_CANCELED);
1003
1004             // If there is anything waiting in the buffer, send it.  I/O may have had a full buffer and
1005             // may not have been able to buffer the full request for which we had credit, so if there
1006             // are still BytesToWrite and we have credit for the current command, we have to buffer
1007             // those and send them if we didn't terminate in an error condition.
1008
1009             // Another possibility is that we don't have credit for the current command.  In that case
1010             // we don't want to wait for BytesToWrite to be 0 or we'll be in a deadlock.  We'll never
1011             // get credit for the command and thus BytesToWrite will never be 0.
1012
1013             // We can only terminate in an error condition if we didn't have credit for the original
1014             // command, so in that case we only have to flush what's in the buffer and not worry about
1015             // the remaining BytesToWrite.
1016
1017             // After we check for these conditions we can send the Prepare to Cancel and Cancel
1018             // Job commands
1019             if( (iCurrBuffSize || (BytesToWrite && bCreditForCommand && !ErrorTerminationState) ) &&
1020                !(bCanceling || bCanceled) )
1021             {
1022                 bFlush = TRUE;
1023             }
1024             else if(!bCanceling)
1025             {
1026                 pWriteBuff = byPrepareToCancel;
1027                 dwWriteCount = sizeof(byPrepareToCancel);
1028                 BytesToWrite = sizeof(byPrepareToCancel);
1029                 byCommandNumber = COMMAND_PREPARE_TO_CANCEL;
1030                 bOriginalRequest = FALSE;
1031                 bCreditForCommand = FALSE;
1032                 byCreditWaitCount = 0;
1033                 bCanceling = TRUE;
1034             }
1035             else if(!bCanceled)
1036             {
1037                 // pWriteBuff will only be equal to byPrepareToCancel when we've setup the Prepare to
1038                 // Cancel command but haven't yet sent it to the printer
1039                 if(pWriteBuff != byPrepareToCancel)
1040                 {
1041                     pWriteBuff = pLDLEncap->pbyCancel;
1042                     dwWriteCount = sizeof(pLDLEncap->pbyCancel);
1043                     BytesToWrite = sizeof(pLDLEncap->pbyCancel);
1044                     byCommandNumber = COMMAND_CANCEL;
1045                     bOriginalRequest = FALSE;
1046                     bCreditForCommand = FALSE;
1047                     byCreditWaitCount = 0;
1048                     bCanceled = TRUE;
1049                 }
1050             }
1051         }
1052     } while (BytesToWrite > 0);
1053
1054     if (bCanceled)
1055     {
1056         // Ensure that display still says we're cancelling
1057         pSS->DisplayPrinterStatus(DISPLAY_PRINTING_CANCELED);
1058         ErrorTerminationState = TRUE;
1059         return JOB_CANCELED;
1060     }
1061     else
1062     {
1063         // Ensure any error message has been cleared
1064         pSS->DisplayPrinterStatus (DISPLAY_PRINTING);
1065         if (bCheckForCancelButton)
1066         {
1067             ulBytesSentSinceCancelCheck += dwWriteCount;
1068         }
1069         return NO_ERROR;
1070     }
1071 }
1072
1073 DRIVER_ERROR DJ3320::ParsePenInfo (PEN_TYPE& ePen, BOOL QueryPrinter)
1074 {
1075
1076     char    *str;
1077     int     num_pens = 0;
1078
1079     DRIVER_ERROR err = SetPenInfo (str, QueryPrinter);
1080     ERRCHECK;
1081
1082     // the first byte indicates how many pens are supported
1083     if ((str[0] >= '0') && (str[0] <= '9'))
1084     {
1085         num_pens = str[0] - '0';
1086     }
1087     else if ((str[0] >= 'A') && (str[0] <= 'F'))
1088     {
1089         num_pens = 10 + (str[0] - 'A');
1090     }
1091     else
1092     {
1093         return BAD_DEVICE_ID;
1094     }
1095
1096     if ((int) strlen (str) < (num_pens * 8))
1097     {
1098         return BAD_DEVICE_ID;
1099     }
1100
1101     char    *p = str + 1;
1102     BYTE    penInfoBits[4];
1103 /*
1104  *  Pen Type Info
1105  *
1106     Bit 31 (1 bit)
1107
1108     1 if these fields describe a print head
1109     0 otherwise
1110     Bit 30 (1 bit)
1111
1112     1 if these fields describe an ink supply
1113     0 otherwise
1114
1115     Bits 29 .. 24 (6 bits) describes the pen/supply type:
1116
1117     0 = none
1118     1 = black
1119     2 = CMY
1120     3 = KCM
1121     4 = Cyan
1122     5 = Meganta
1123     6 = Yellow
1124         7 = Cyan - low dye load 
1125     8 = Magenta - low dye load 
1126     9 = Yellow - low dye load (may never be used, but reserve space anyway) [def added Jun 3, 2002]
1127     10 = gGK - two shades of grey plus black; g=light grey, G=medium Grey, K=black  [added Sep 12, 02]
1128     11 .. 62 = reserved for future use
1129     63=Unknown
1130  */
1131     ePen = NO_PEN;
1132
1133     for (int i = 0; i < num_pens; i++, p += 8)
1134     {
1135                 AsciiHexToBinary (penInfoBits, p, 8);
1136         if ((penInfoBits[1] & 0xf8) == 0xf8)
1137         {
1138 //          The high 5 bits in the 3rd and 4th nibble (second byte) identify the
1139 //          installed pen. If all 5 bits are on, user has installed an incompatible pen.
1140             return UNSUPPORTED_PEN;
1141         }
1142         if ((penInfoBits[0] & 0x80) != 0x80)        // if Bit 31 is 0, this is not a pen
1143         {
1144             continue;
1145         }
1146         BYTE penColor = penInfoBits[0] & 0x3F;
1147         switch (penColor)
1148         {
1149             case 0:
1150             {
1151                 break;
1152             }
1153             case 1:
1154                 ePen = BLACK_PEN;
1155                 break;
1156             case 2:
1157             {
1158                 if (ePen == BLACK_PEN)
1159                 {
1160                     ePen = BOTH_PENS;
1161                 }
1162                 else if (ePen == MDL_PEN)
1163                 {
1164                     ePen = MDL_BOTH;
1165                 }
1166                 else
1167                 {
1168                     ePen = COLOR_PEN;
1169                 }
1170                 break;
1171             }
1172             case 3:
1173                 if (ePen == BLACK_PEN)
1174                 {
1175                     ePen = MDL_AND_BLACK_PENS;
1176                 }
1177                 else if (ePen == COLOR_PEN)
1178                 {
1179                     ePen = MDL_BOTH;
1180                 }
1181                 else if (ePen == BOTH_PENS)
1182                 {
1183                     ePen = MDL_BLACK_AND_COLOR_PENS;
1184                 }
1185                 else
1186                 {
1187                     ePen = MDL_PEN;
1188                 }
1189                 break;
1190             case 4:             // cyan pen
1191             case 5:             // magenta pen
1192             case 6:             // yellow pen
1193             case 7:             // low dye load cyan pen
1194             case 8:             // low dye load magenta pen
1195             case 9:             // low dye load yellow pen
1196                 if (ePen == BLACK_PEN || ePen == BOTH_PENS)
1197                 {
1198                     ePen = BOTH_PENS;
1199                 }
1200                 else
1201                 {
1202                     ePen = COLOR_PEN;
1203                 }
1204                 break;
1205             default:
1206                 ePen = UNKNOWN_PEN;
1207         }
1208     }
1209
1210     return NO_ERROR;
1211 }
1212
1213 DRIVER_ERROR DJ3320::VerifyPenInfo()
1214 {
1215
1216     DRIVER_ERROR err = NO_ERROR;
1217
1218     if(IOMode.bDevID == FALSE)
1219         return err;
1220
1221     ePen = NO_PEN;
1222
1223     err = ParsePenInfo(ePen);
1224     ERRCHECK;
1225
1226     while (ePen == NO_PEN)
1227     {
1228         err = ParsePenInfo (ePen);
1229         ERRCHECK;
1230         if (ePen == NO_PEN)
1231         {
1232             pSS->DisplayPrinterStatus (DISPLAY_NO_PENS);
1233             if (pSS->BusyWait (500) == JOB_CANCELED)
1234                 return JOB_CANCELED;
1235         }
1236
1237     }
1238
1239     pSS->DisplayPrinterStatus (DISPLAY_PRINTING);
1240
1241     return NO_ERROR;
1242 }
1243
1244 DRIVER_ERROR DJ3320::CheckInkLevel()
1245 {
1246     DRIVER_ERROR err;
1247     char* pStr;
1248
1249     BYTE bDevIDBuff[DevIDBuffSize];
1250
1251     if (!IOMode.bDevID)
1252     {
1253         return NO_ERROR;
1254     }
1255
1256     err = pSS->GetDeviceID(bDevIDBuff, DevIDBuffSize, TRUE);
1257     if (err!=NO_ERROR)
1258     {
1259         return NO_ERROR;
1260     }
1261
1262     if ( (pStr=(char *)strstr((const char*)bDevIDBuff+2,";S:")) == NULL )
1263     {
1264         return NO_ERROR;
1265     }
1266
1267     pStr += 21;
1268     int     numPens = 0;
1269     if (*pStr > '0' && *pStr < '9')
1270     {
1271         numPens = *pStr - '0';
1272     }
1273     else if (*pStr > 'A' && *pStr < 'F')
1274     {
1275         numPens = *pStr - 'A';
1276     }
1277     else if (*pStr > 'a' && *pStr < 'f')
1278     {
1279         numPens = *pStr - 'a';
1280     }
1281
1282     pStr++;
1283
1284         BYTE    penInfoBits[4];
1285     BYTE    blackink = 0;
1286     BYTE    colorink = 0;
1287     BYTE    photoink = 0;
1288     BYTE    greyink = 0;
1289     for (int i = 0; i < numPens; i++, pStr += 8)
1290     {
1291         AsciiHexToBinary (penInfoBits, pStr, 8);
1292
1293         if ((penInfoBits[0] & 0x80) != 0x80)        // if Bit 31 is 0, this is not a pen
1294         {
1295             continue;
1296         }
1297         int penColor = penInfoBits[0] & 0x3F;
1298         switch (penColor)
1299         {
1300             case 1:
1301                 blackink =  penInfoBits[1] & 0x7;
1302                 break;
1303             case 2:
1304                 colorink =  penInfoBits[1] & 0x7;
1305                 break;
1306             case 3:
1307                 photoink =  penInfoBits[1] & 0x7;
1308                 break;
1309             case 10:
1310                 greyink =  penInfoBits[1] & 0x7;
1311                 break;
1312             case 4:
1313             case 5:
1314             case 6:
1315             case 7:
1316             case 8:
1317             case 9:
1318                 colorink = penInfoBits[1] & 0x7;   // REVISIT: these are C, M, Y respectively
1319                 break;
1320             default:
1321                 break;
1322         }
1323     }
1324     if (blackink < 2 && colorink < 2 && photoink < 2 && greyink < 2)
1325     {
1326         return NO_ERROR;
1327     }
1328     else if (blackink > 1 && colorink > 1 && photoink > 1)
1329     {
1330         return WARN_LOW_INK_COLOR_BLACK_PHOTO;
1331     }
1332     else if (greyink > 1 && colorink > 1 && photoink > 1)
1333     {
1334         return WARN_LOW_INK_COLOR_GREY_PHOTO;
1335     }
1336     else if (blackink > 1 && colorink > 1)
1337     {
1338         return WARN_LOW_INK_BOTH_PENS;
1339     }
1340     else if (blackink > 1 && photoink > 1)
1341     {
1342         return WARN_LOW_INK_BLACK_PHOTO;
1343     }
1344     else if (greyink > 1 && colorink > 1)
1345     {
1346         return WARN_LOW_INK_COLOR_GREY;
1347     }
1348     else if (greyink > 1 && photoink > 1)
1349     {
1350         return WARN_LOW_INK_GREY_PHOTO;
1351     }
1352     else if (colorink > 1 && photoink > 1)
1353     {
1354         return WARN_LOW_INK_COLOR_PHOTO;
1355     }
1356     else if (blackink > 1)
1357     {
1358         return WARN_LOW_INK_BLACK;
1359     }
1360     else if (colorink > 1)
1361     {
1362         return WARN_LOW_INK_COLOR;
1363     }
1364     else if (photoink > 1)
1365     {
1366         return WARN_LOW_INK_PHOTO;
1367     }
1368     else if (greyink > 1)
1369     {
1370         return WARN_LOW_INK_GREY;
1371         }
1372     else if (colorink > 1)
1373     {
1374         return WARN_LOW_INK_COLOR;
1375     }
1376         else
1377         {
1378                 return NO_ERROR;
1379         }
1380 } //CheckInkLevel
1381
1382
1383 DRIVER_ERROR DJ3320::SkipRasters (int nBlankRasters)
1384 {
1385     return (pLDLEncap->SetVerticalSkip (nBlankRasters));
1386 }
1387
1388 DRIVER_ERROR DJ3320::CleanPen()
1389 {
1390     return pLDLEncap->CleanPen ();
1391 }
1392
1393 DRIVER_ERROR DJ3320::Flush (int FlushSize)
1394 {
1395     pLDLEncap->Flush ();
1396     return NO_ERROR;
1397 }
1398
1399 Header3320::Header3320 (Printer* p,PrintContext* pc)
1400     : Header(p,pc)
1401 {
1402
1403 }
1404
1405 DRIVER_ERROR Header3320::FormFeed ()
1406 {
1407     return (((DJ3320 *) thePrinter)->pLDLEncap->EndPage ());
1408 }
1409
1410 DRIVER_ERROR Header3320::EndJob()
1411 {
1412     ((DJ3320 *) thePrinter)->pLDLEncap->EndJob ();
1413     return NO_ERROR;
1414 }
1415
1416 DRIVER_ERROR Header3320::Send ()
1417 {
1418
1419     DJ3320  *pXBow = (DJ3320 *) thePrinter;
1420
1421     return (pXBow->pLDLEncap->StartJob ());
1422
1423 }
1424
1425 DRIVER_ERROR Header3320::SendCAPy (unsigned int iAbsY)
1426 {
1427     return NO_ERROR;
1428 }
1429
1430 LDLEncap::LDLEncap (DJ3320 *pPrinter, SystemServices *pSys, PrintContext *pc)
1431 {
1432
1433     constructor_error = NO_ERROR;
1434     piCreditCount = NULL;
1435     m_pSys = pSys;
1436     pPrinterXBow = pPrinter;
1437     m_iXResolution = pc->EffectiveResolutionX ();
1438     m_iYResolution = pc->EffectiveResolutionY ();
1439     m_pthisPC = pc;
1440     m_cPrintDirection = PRNDRN_LEFTTORIGHT;
1441     m_SwathData = NULL;
1442     m_sRefCount = 6;
1443     m_iBlankRasters = 0;
1444     m_iRasterCount = 0;
1445     m_iVertPosn = (int) (m_pthisPC->PrintableStartY () * DEVUNITS_XBOW);
1446     m_iNumColors = 4;
1447     m_iLeftMargin = (int) (m_pthisPC->PrintableStartX () * DEVUNITS_XBOW);
1448
1449     ////////////////////////////////////////////////////////////////////////////////////
1450     float   fXOverSpray = 0.0;
1451     float   fYOverSpray = 0.0;
1452     float   fLeftOverSpray = 0.0;
1453     float   fTopOverSpray  = 0.0;
1454         FullbleedType   fbType;
1455     if (m_pthisPC->bDoFullBleed &&
1456         pPrinterXBow->FullBleedCapable (m_pthisPC->thePaperSize,
1457                                                                           &fbType,
1458                                       &fXOverSpray, &fYOverSpray,
1459                                       &fLeftOverSpray, &fTopOverSpray))
1460     {
1461
1462                 /*
1463                  *      To get the printer to do fullbleed printing, move the vertical postion 
1464                  *      to cover the overspary. Overspray is needed to take care of
1465                  *      skew during paper pick. These values may be mech dependent.
1466                  *      Currently, supported only on PhotoSmart 100, Malibu. DJ3600 supports
1467                  *      fullbleed printing also. The current values for overspray are
1468                  *      0.059 inch for top, bottom and left edges and 0.079 for right edge.
1469                  */
1470                 m_iVertPosn = (int) (-fTopOverSpray * DEVUNITS_XBOW);
1471                 m_iLeftMargin = (int) (-fLeftOverSpray * DEVUNITS_XBOW);
1472     }
1473
1474     m_bStartPageNotSent = TRUE;
1475
1476     m_iNextRaster = 0;
1477     m_iNextColor  = 0;
1478
1479     m_iBitDepth = 1;
1480     m_cPlaneNumber = 0;
1481     m_cPrintQuality = (BYTE) QUALITY_NORMAL;
1482     m_cMediaType    = (BYTE) MEDIA_PLAIN;
1483
1484     BYTE    cm = COLOR;
1485     QUALITY_MODE cqm;
1486     MEDIATYPE cmt;
1487     COLORMODE ccm;
1488     BOOL cdt;
1489     DRIVER_ERROR err = m_pthisPC->GetPrintModeSettings (cqm, cmt, ccm, cdt);
1490     if (err == NO_ERROR)
1491     {
1492         if (cqm == QUALITY_BEST && cmt == MEDIA_PHOTO)
1493             m_iBitDepth = 2;
1494         m_cPrintQuality = (BYTE) cqm;
1495         m_cMediaType    = (BYTE) cmt;
1496         cm = (BYTE) ccm;
1497     }
1498
1499     if (pPrinterXBow->ePen == BLACK_PEN || pPrinterXBow->ePen == MDL_PEN || cm == GREY_K)
1500         m_iNumColors = 1;
1501     else if (pPrinterXBow->ePen == COLOR_PEN || cm == GREY_CMY)
1502         m_iNumColors = 3;
1503         else if (pPrinterXBow->ePen == BOTH_PENS && m_iBitDepth == 2)
1504                 m_iNumColors = 3;
1505         else if (pPrinterXBow->ePen == MDL_BOTH)
1506                 m_iNumColors = 6;
1507
1508     m_bBidirectionalPrintingOn = TRUE; //FALSE;
1509
1510     UInt16 mem_needed =   SIZEOF_LDLHDR
1511                         + SIZEOF_LDL_PRTSWP_CMDOPT
1512                         + SIZEOF_LDL_PRTSWP_OPTFLDS
1513                         + 6 * SIZEOF_LDL_PRTSWP_COLROPT
1514                         + SIZEOF_LDL_COLROPT_ACTIVECOLR
1515                         + SIZEOF_LDLTERM;
1516     m_szCmdBuf = new BYTE[mem_needed];
1517     CNEWCHECK (m_szCmdBuf);
1518
1519     m_bLittleEndian = TRUE;
1520     {
1521         union
1522         {
1523             short   a;
1524             char    b[2];
1525         }c;
1526         c.a = 0x1234;
1527         if (c.b[0] == 0x12)
1528             m_bLittleEndian = FALSE;
1529     }
1530
1531     m_szCmdBuf[0] = FRAME_SYN;
1532     m_szCmdBuf[1] = 0;
1533     m_szCmdBuf[3] = 0;
1534     m_szCmdBuf[4] = 0;
1535     m_szCmdBuf[5] = 0;
1536     m_szCmdBuf[6] = 0;
1537     m_szCmdBuf[8] = 0;
1538
1539     // Pacing and status handling data
1540     bNewStatus = FALSE;
1541     memset(byStatusBuff, 0, sizeof(byStatusBuff));
1542
1543     m_pbyPacketBuff = NULL;
1544     m_pbyPacketBuff = pSys->AllocMem (MAX_PACKET_READ_SIZE);
1545     CNEWCHECK (m_pbyPacketBuff);
1546
1547     m_dwPacketBuffSize = MAX_PACKET_READ_SIZE;
1548
1549     // Setup Sync command
1550     pbySync = m_pSys->AllocMem(SYNCSIZE);
1551     CNEWCHECK(pbySync);
1552
1553     memset(pbySync, 0, SYNCSIZE);
1554     memcpy(pbySync, bySync, sizeof(bySync));
1555     memset((pbySync + sizeof(bySync)), 0, SYNC_CMD_OPT_SIZE);
1556     pbySync[sizeof(bySync) + SYNC_CMD_OPT_SIZE] = FRAME_SYN;
1557     memset((pbySync + sizeof(bySync) + SYNC_CMD_OPT_SIZE + sizeof(FRAME_SYN)), 0, LDL_MAX_IMAGE_SIZE);
1558
1559 /*
1560  *  Alignment Values.
1561  *  Currently, only Black to Color Vertical Alignment value is used.
1562  *  This value should really be obtained by running the pen alignment test.
1563  *  A value of 12 device units seems to be a good default.
1564  */
1565         BYTE cVertAlign = 0;
1566         if (pPrinterXBow->ePen == BOTH_PENS)
1567         {
1568                 if (pSys->GetVerticalAlignmentValue(&cVertAlign))
1569                 {
1570                         m_cKtoCVertAlign = cVertAlign;
1571                 }
1572                 else
1573                 {
1574                         m_cKtoCVertAlign = 12;
1575                 }
1576         }
1577         else if (pPrinterXBow->ePen == MDL_BOTH)
1578         {
1579                 if (pSys->GetVerticalAlignmentValue(&cVertAlign))
1580                 {
1581                         m_cPtoCVertAlign = cVertAlign;
1582                 }
1583                 else
1584                 {
1585                         m_cPtoCVertAlign = 6;
1586                 }
1587         }
1588         else
1589         {
1590                 m_cKtoCVertAlign = 12;
1591                 m_cPtoCVertAlign = 6;
1592         }
1593 }
1594
1595 void LDLEncap::AllocateSwathBuffer (unsigned int RasterSize)
1596 {
1597     int size = RasterSize;
1598     size = (size / 8 + 1) * 8;
1599     m_iImageWidth = size;
1600
1601     constructor_error = NO_ERROR;
1602     m_ldlCompressData = NULL;
1603
1604 #ifdef  APDK_LDL_COMPRESS
1605     if (pPrinterXBow->m_iLdlVersion == 1)
1606     {
1607         m_ldlCompressData = new comp_ptrs_t;
1608     }
1609 #endif
1610
1611     if (m_iBitDepth == 2)
1612     {
1613         size *= 2;
1614     }
1615
1616     int     iSwings = pPrinterXBow->m_iBytesPerSwing / 2;
1617     int     iCompressBufSize = iSwings * LDL_MAX_IMAGE_SIZE+20;    // additional space for load sweep command
1618     m_szCompressBuf = new BYTE[iCompressBufSize];
1619     CNEWCHECK (iCompressBufSize);
1620     memset (m_szCompressBuf, 0, iCompressBufSize);
1621
1622     BYTE    *p = NULL;
1623     int     iSwathBuffSize;
1624
1625     m_sSwathHeight = SWATH_HEIGHT;
1626
1627         /*
1628          *  This swath buffer cannot be greater than the number of nozzles - 400 for black
1629          *  and 100 for color - we can use.
1630          */\r
1631 \r
1632     int    iAdjHeight = (pPrinterXBow->m_iNumBlackNozzles / 32) * 8;
1633     if (pPrinterXBow->ePen == BLACK_PEN)
1634     {
1635         m_sSwathHeight = m_sSwathHeight * 4;
1636         if (m_sSwathHeight * 1200 / m_iYResolution > pPrinterXBow->m_iNumBlackNozzles)
1637             m_sSwathHeight = m_iYResolution / 3;
1638     }
1639     else if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution > 300 && m_iNumColors > 1 && m_iBitDepth == 1) // Collie change
1640     {
1641         m_sSwathHeight = (m_sSwathHeight / 4) * 4 * 2;
1642         if (m_sSwathHeight > 200)
1643             m_sSwathHeight = 200;
1644     }
1645
1646     else if (m_iBitDepth == 2)
1647         m_sSwathHeight = iAdjHeight * 4;
1648
1649     if (m_cPrintQuality == QUALITY_NORMAL)
1650         m_sSwathHeight = iAdjHeight * 2;
1651
1652     if (m_cPrintQuality == QUALITY_DRAFT && pPrinterXBow->ePen != BLACK_PEN)
1653     {
1654         m_sSwathHeight *= iSwings;
1655     }
1656
1657     while (m_sSwathHeight > 16)
1658     {
1659         iSwathBuffSize = m_iNumColors * sizeof (BYTE *) +
1660                          m_iNumColors * m_sSwathHeight * sizeof (BYTE *) +
1661                          size * m_iNumColors * m_sSwathHeight;
1662         if ((p = m_pSys->AllocMem(iSwathBuffSize)) == NULL)
1663         {
1664             m_sSwathHeight = (m_sSwathHeight / 16) * 8;
1665             continue;
1666         }
1667         break;
1668     }
1669     if (m_sSwathHeight < 16)
1670     {
1671         m_sSwathHeight = 16;
1672         iSwathBuffSize = m_iNumColors * sizeof (BYTE *) +
1673                          m_iNumColors * m_sSwathHeight * sizeof (BYTE *) +
1674                          size * m_iNumColors * m_sSwathHeight;
1675         p = m_pSys->AllocMem(iSwathBuffSize);
1676         CNEWCHECK (p);
1677     }
1678
1679     int     i;
1680     m_SwathData = (BYTE ***) p;
1681     for (i = 0; i < m_iNumColors; i++)
1682         m_SwathData[i] = (BYTE **) (p + sizeof (BYTE *) * m_iNumColors + i * m_sSwathHeight * sizeof (BYTE *));
1683
1684     for (i = 0; i < m_iNumColors; i++)
1685     {
1686         p = (BYTE *) m_SwathData + sizeof (BYTE *) * m_iNumColors +
1687                 m_iNumColors * m_sSwathHeight * sizeof (BYTE *) +
1688                 size * m_sSwathHeight * i;
1689         for (int j = 0; j < m_sSwathHeight; j++)
1690         {
1691             memset (p, 0, size);
1692             m_SwathData[i][j] = p;
1693             p = p + size;
1694         }
1695     }
1696
1697     if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
1698     {
1699         m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * m_iNumColors;
1700         m_iVertPosn -= (((m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * 600 / m_iYResolution) * DEVUNITS_XBOW / 600);
1701     }
1702     m_cPassNumber = 0;
1703
1704     float   fXOverSpray = 0.0;
1705     float   fYOverSpray = 0.0;
1706     float   fLeftOverSpray = 0.0;
1707     float   fTopOverSpray  = 0.0;
1708         FullbleedType   fbType;
1709     if (m_pthisPC->bDoFullBleed &&
1710         pPrinterXBow->FullBleedCapable (m_pthisPC->thePaperSize,
1711                                                                           &fbType,
1712                                       &fXOverSpray, &fYOverSpray,
1713                                       &fLeftOverSpray, &fTopOverSpray))
1714         {
1715                 if (m_iVertPosn < -850) m_iVertPosn = -850;
1716         }
1717         else
1718         {
1719                 if (m_iVertPosn < -600) m_iVertPosn = -600;
1720         }
1721     if (m_iBitDepth == 2)
1722         m_iVertPosn += 6;
1723 }
1724
1725 unsigned int LDLEncap::GetSwathWidth (int iStart, int iLast, int iWidth)
1726 {
1727     int k;
1728     int i, j;
1729     for (i = iWidth - 1 /*sizeof (long)*/; i > -1; i--)
1730     {
1731         for (j = iStart; j < iLast; j++)
1732         {
1733             for (k = m_iRasterCount / m_iNumColors-1; k >= 0; k--)
1734             {
1735
1736                 if (m_SwathData[j][k][i])
1737                 {
1738                     return (i+1);
1739                 }
1740             }
1741         }
1742     }
1743
1744     return 0;
1745 }
1746
1747 void LDLEncap::Flush ()
1748 {
1749 //  if (m_iRasterCount)
1750 //      Process (NULL, 0);
1751 }
1752
1753 DRIVER_ERROR LDLEncap::SetVerticalSkip (int nBlankRasters)
1754 {
1755     DRIVER_ERROR    err = NO_ERROR;
1756 #if 0
1757     if (m_iRasterCount == 0)
1758     {
1759         m_iBlankRasters += nBlankRasters;
1760         return err;
1761     }
1762 #endif
1763     int     iCount = m_iNumColors * m_iBitDepth;
1764     if (m_iBitDepth == 2 && m_iNumColors != 6)
1765         iCount++;
1766
1767     while (nBlankRasters > 0)
1768     {
1769         for (int i = 0; i < iCount; i++)
1770         {
1771             err = Encapsulate (NULL, m_iImageWidth, 0);
1772             ERRCHECK;
1773         }
1774         nBlankRasters--;
1775     }
1776     return err;
1777 }
1778
1779 BOOL LDLEncap::IsBlankRaster (BYTE *raster, int width)
1780 {
1781     while (width > 0)
1782     {
1783         if (*raster)
1784             return FALSE;
1785         width--;
1786     }
1787     return FALSE;
1788 }
1789
1790 DRIVER_ERROR LDLEncap::Encapsulate (const BYTE *input, DWORD size, BOOL bLastPlane)
1791 {
1792     DRIVER_ERROR    err = NO_ERROR;
1793     int iPlaneNum = 0;
1794     if (size > (DWORD) m_iImageWidth)
1795         size = m_iImageWidth;
1796     if (m_iBitDepth == 2)
1797     {
1798                 if (m_iNumColors != 6)
1799                 {
1800                         if (m_cPlaneNumber == 0)
1801                         {
1802                                 m_cPlaneNumber++;
1803                                 return NO_ERROR;
1804                         }
1805                 }
1806         int iCPlane;
1807                 if (m_iNumColors == 6)
1808                 {
1809                         iPlaneNum = m_cPlaneNumber % 2;
1810                 }
1811                 else
1812                 {
1813                         iPlaneNum = (m_cPlaneNumber + 1) % 2;
1814                 }
1815         int iRowNum = (m_iRasterCount / 6) * 2 + iPlaneNum;
1816         iRowNum = m_iNextRaster;
1817                 if (m_iNumColors == 6)
1818                 {
1819                         iCPlane = m_cPlaneNumber / 2;
1820                 }
1821                 else
1822                 {
1823                         iCPlane = (m_cPlaneNumber - 1) / 2;
1824                 }
1825         if (iPlaneNum == 0)
1826         {
1827             if (!input)
1828                 memset (m_SwathData[iCPlane][iRowNum], 0, m_iImageWidth * 2);
1829             else
1830                 memcpy (m_SwathData[iCPlane][iRowNum], input, size);
1831         }
1832                 if (m_iNumColors == 6)
1833                 {
1834                         m_cPlaneNumber = (m_cPlaneNumber + 1) % 12;
1835                 }
1836                 else
1837                 {
1838                         m_cPlaneNumber = (m_cPlaneNumber + 1) % 8;
1839                 }
1840
1841         if (iPlaneNum == 1)
1842         {
1843             // do the dotmapping here
1844             BYTE    cbyte1, cbyte2;
1845             BYTE    c1, c2;
1846             int     j = 0;
1847             BYTE    r1b1 = 0;
1848             BYTE    r1b2 = 0;
1849             BYTE    r2b1 = 0;
1850             BYTE    r2b2 = 0;
1851             BYTE    bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
1852
1853             // Collie changes
1854             int     iNextBitPos = m_iImageWidth;
1855             int     iJIncrement = 1;
1856             if (pPrinterXBow->m_iLdlVersion == 2)
1857             {
1858                 iNextBitPos = 1;
1859                 iJIncrement = 2;
1860             }
1861
1862             memcpy (m_szCompressBuf, m_SwathData[iCPlane][m_iNextRaster], size);
1863
1864             static  BYTE    rand_table[4][4] = {{0, 3, 1, 2},
1865                                                 {3, 1, 2, 0},
1866                                                 {1, 2, 0, 3},
1867                                                 {2, 0, 3, 1}};
1868
1869             BYTE    rt1, rt2;
1870             rt1 = iRowNum % 4;
1871
1872             for (unsigned int i = 0; i < size; i++)
1873             {
1874                 cbyte2 = m_szCompressBuf[i];
1875                 cbyte1 = (input == NULL) ? 0 : input[i];
1876
1877 //              1200 dpi raster split into 2 600 dpi rasters
1878
1879                 r1b1 = 0;
1880                 r1b2 = 0;
1881                 r2b1 = 0;
1882                 r2b2 = 0;
1883
1884                 for (int ibit = 0; ibit < 8; ibit++)
1885                 {
1886                     c1 = (cbyte1 & bitmask[ibit]) ? 1 : 0;
1887                     c2 = (cbyte2 & bitmask[ibit]) ? 1 : 0;
1888                     c1 = 2 * c1 + c2;
1889
1890                     rt2 = (i + ibit) % 4;
1891                     rt2 = rand_table[rt1][rt2];
1892
1893                     if (c1 == 2)
1894                     {
1895                         if (rt2 == 0)
1896                         {
1897                             r1b1 = r1b1 | (0xff & (cbyte1 & bitmask[ibit]));
1898                             r2b2 = r2b2 | (0xff & bitmask[ibit]);
1899                         }
1900                         else if (rt2 == 1)
1901                         {
1902                             r1b2 = r1b2 | (0xff & bitmask[ibit]);
1903                             r2b1 = r2b1 | (0xff & bitmask[ibit]);
1904                         }
1905
1906                         else if (rt2 == 2)
1907                         {
1908                             r1b1 = r1b1 | (0xff & bitmask[ibit]);
1909                             r2b1 = r2b1 | (0xff & bitmask[ibit]);
1910                         }
1911                         else if (rt2 == 3)
1912                         {
1913                             r1b2 = r1b2 | (0xff & bitmask[ibit]);
1914                             r2b2 = r2b2 | (0xff & bitmask[ibit]);
1915                         }
1916
1917                     }
1918                     else if (c1 == 1)
1919                     {
1920                         if (rt2 == 0)
1921                             r1b1 = r1b1 | (0xff & bitmask[ibit]);
1922                         else if (rt2 == 1)
1923                             r1b2 = r1b2 | (0xff & bitmask[ibit]);
1924                         else if (rt2 == 2)
1925                             r2b1 = r2b1 | (0xff & bitmask[ibit]);
1926                         else
1927                             r2b2 = r2b2 | (0xff & bitmask[ibit]);
1928
1929                     }
1930                     else if (c1 == 3)
1931                     {
1932                         r1b1 = r1b1 | (0xff & bitmask[ibit]);
1933                         r1b2 = r1b2 | (0xff & bitmask[ibit]);
1934                         r2b1 = r2b1 | (0xff & bitmask[ibit]);
1935                         r2b2 = r2b2 | (0xff & bitmask[ibit]);
1936                     }
1937                 }
1938                 m_SwathData[iCPlane][m_iNextRaster][j] = r1b1;
1939                 m_SwathData[iCPlane][m_iNextRaster][j+iNextBitPos] = r1b2;
1940                 m_SwathData[iCPlane][m_iNextRaster+1][j]   = r2b1;
1941                 m_SwathData[iCPlane][m_iNextRaster+1][j+iNextBitPos] = r2b2;
1942
1943                 j += iJIncrement;
1944             }
1945
1946                         if (m_iNumColors == 6)
1947                         {
1948                                 m_cPlaneNumber = m_cPlaneNumber % 12;
1949                         }
1950                         else
1951                         {
1952                                 m_cPlaneNumber = m_cPlaneNumber % 7;
1953                         }
1954         }
1955     }
1956     else
1957     {
1958         if (!input || size == 0)
1959             memset (m_SwathData[m_iNextColor][m_iNextRaster], 0, m_iImageWidth);
1960         else
1961             memcpy (m_SwathData[m_iNextColor][m_iNextRaster], input, size);
1962     }
1963     m_iRasterCount++;
1964     if (m_iBitDepth == 1 || (m_iBitDepth == 2 && iPlaneNum == 1))
1965         m_iNextColor++;
1966     if (m_iNextColor == m_iNumColors)
1967     {
1968         m_iNextColor = 0;
1969         if (m_iBitDepth == 2)
1970             m_iNextRaster += 2;
1971         else
1972             m_iNextRaster++;
1973     }
1974     if (m_iRasterCount < m_sSwathHeight * m_iNumColors)
1975         return NO_ERROR;
1976
1977     if (m_bStartPageNotSent)
1978     {
1979         err = StartPage ();
1980         if (err != NO_ERROR)
1981             return err;
1982     }
1983
1984     err = ProcessSwath (size);
1985
1986     if (m_iNextRaster >= m_sSwathHeight)
1987     {
1988         m_iNextRaster = 0;
1989     }
1990     return err;
1991 }
1992
1993 DRIVER_ERROR LDLEncap::ProcessSwath (int iCurRasterSize)
1994 {
1995
1996     DRIVER_ERROR    err = NO_ERROR;
1997     unsigned int    start = 0;
1998     int             size = 0;
1999     Int32           iVertPosn;
2000     Int16           sCurSwathHeight = m_iRasterCount / m_iNumColors;
2001     Int32           LeftEdge  = 0;
2002     int i;
2003     m_iVertPosn += ((m_iBlankRasters) * 600 / m_iYResolution) * DEVUNITS_XBOW / 600;
2004     m_iBlankRasters = 0;
2005
2006     iVertPosn = m_iVertPosn;
2007
2008     BOOL    bColorPresent = TRUE;
2009     BOOL    bBlackPresent = TRUE;
2010         BOOL    bPhotoPresent = TRUE;
2011     short   sColorSize = 0;
2012
2013     int     StartColor = 0;
2014     int     LastColor  = 1;
2015     Int32   RightEdge;
2016     int     delta = 2;
2017     int     iColors = 0;
2018     UInt32  uiSwathSize = 0;
2019
2020     int     iSwings = pPrinterXBow->m_iBytesPerSwing;
2021
2022     if (m_iNumColors == 1)
2023         {
2024         bColorPresent = 0;
2025         bPhotoPresent = 0;
2026 /* 
2027                 if (pPrinterXBow->ePen == BLACK_PEN)
2028                         bPhotoPresent = 0;
2029                 else
2030                         bBlackPresent = 0;
2031  */
2032         }
2033     if (m_iNumColors == 3)
2034         {
2035         bBlackPresent = 0;
2036                 bPhotoPresent = 0;
2037         }
2038     if (m_iNumColors == 6)
2039         {
2040         bBlackPresent = 0;
2041         }
2042     if (m_iNumColors == 4)
2043         {
2044         bPhotoPresent = 0;
2045         }
2046
2047     if (!m_bBidirectionalPrintingOn)
2048         m_cPrintDirection = PRNDRN_LEFTTORIGHT;
2049
2050     Int16   j;
2051     int     n;
2052     int     count;
2053     int     iStartRaster = m_cPassNumber % (2 * m_iBitDepth);
2054     BYTE    mask = 0xFF;
2055
2056     if (pPrinterXBow->m_iLdlVersion == 2)
2057     {
2058         iStartRaster = 0;   // Version 2 - REVISIT
2059     }
2060
2061     if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
2062     {
2063         if ((m_cPassNumber % (4 * m_iBitDepth)) < (2 * m_iBitDepth))
2064             mask = 0xAA;
2065         else
2066             mask = 0x55;
2067     }
2068
2069 /*
2070  *  Photo Swath
2071  */
2072
2073     BYTE    csavMask = mask;
2074
2075         Int16       iOffset = 0;
2076
2077     if (m_sRefCount > 64000)
2078         m_sRefCount = 6;
2079
2080     if (bPhotoPresent)
2081     {
2082                 if (bColorPresent)
2083                 {
2084                         iColors = 6;
2085                         LastColor = 6;
2086                         StartColor = 0;
2087             if (pPrinterXBow->m_iLdlVersion == 1)
2088             {
2089                             // 1200 dpi split into two
2090                             size = GetSwathWidth (StartColor, LastColor, iCurRasterSize/* * m_iBitDepth*/);
2091             }
2092             else
2093             {
2094                 size = GetSwathWidth (StartColor, LastColor, iCurRasterSize * m_iBitDepth);
2095             }
2096                 }
2097                 else
2098                 {
2099                         iColors = 1;
2100                         LastColor = 1;
2101                         StartColor = 0;
2102                         // 1200 dpi split into two
2103                         size = GetSwathWidth (StartColor, LastColor, iCurRasterSize/* * m_iBitDepth*/);
2104                 }
2105     }
2106
2107     if (bPhotoPresent && size)
2108     {
2109         if (size % iSwings)
2110             size = ((size/iSwings) + 1) * iSwings;
2111         if (pPrinterXBow->m_iLdlVersion == 1)
2112         {
2113             RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2114                                     (DEVUNITS_XBOW / 600);
2115         }
2116         else
2117         {
2118             RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2119                                     (DEVUNITS_XBOW / (600 * m_iBitDepth));
2120         }
2121         Int16   sLastNozzle;
2122         Int16   sFirstNozzle = 1;
2123         unsigned int    uSweepSize;
2124         int     jDelta = m_iYResolution / pPrinterXBow->m_iColorPenResolution;
2125         jDelta *= m_iBitDepth;
2126
2127         uiSwathSize = size * iColors * sCurSwathHeight / jDelta;
2128
2129         uSweepSize = sCurSwathHeight * iSwings / jDelta;
2130         n = LDL_MAX_IMAGE_SIZE / (uSweepSize);
2131         count = 0;
2132
2133         if (m_iBitDepth == 2)
2134             iStartRaster = (4 - (iStartRaster+1)) % 4;
2135
2136         if (pPrinterXBow->m_iLdlVersion == 2)
2137         {
2138             iStartRaster = 0;   // Collie - REVISIT
2139         }
2140
2141         sLastNozzle = sFirstNozzle - 1 + sCurSwathHeight / jDelta;
2142
2143         BYTE *cb = m_szCompressBuf + 16;    // load sweep command
2144         memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2145
2146         
2147                 // 1200 dpi split into two
2148         int    ib = 0;
2149
2150         if (m_iYResolution > 300 && m_cPrintQuality != QUALITY_DRAFT)
2151         {
2152             iOffset = (sCurSwathHeight / (4 * m_iBitDepth));
2153             iOffset = iOffset + iOffset * ((m_cPassNumber) % (4 * m_iBitDepth));
2154         }
2155
2156         BYTE    cVertAlign = 0;
2157
2158         if (bColorPresent)
2159         {
2160             cVertAlign = m_cPtoCVertAlign;
2161         }
2162
2163         for (ib = 0; ib < (int) m_iBitDepth; ib++)
2164         {
2165             if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
2166             {
2167                 start = size - iSwings;
2168                 delta = -iSwings;
2169             }
2170             else
2171             {
2172                 start = 0;
2173                 delta = iSwings;
2174             }
2175
2176             err = PrintSweep (uiSwathSize, bColorPresent, FALSE, bPhotoPresent,
2177                               iVertPosn+cVertAlign, LeftEdge, RightEdge, m_cPrintDirection,
2178                               sFirstNozzle, sLastNozzle);
2179             ERRCHECK;
2180
2181             i = start + ib * m_iImageWidth;     // 1200 dpi split into two
2182             for (int l = 0; l < size; l += iSwings)   // Collie
2183             {
2184                                 for (int k = StartColor+1; k < LastColor; k++)
2185                                 {
2186                                         mask = csavMask;
2187                                         for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
2188                                         {
2189                         for (int is = 0; is < iSwings; is++)
2190                         {
2191                                                     *cb++ = m_SwathData[k][j][i+is]   & mask;
2192                         }
2193                                                 mask = ~mask;
2194                                         }
2195                                         for (j = iStartRaster; j < iOffset; j += jDelta)
2196                                         {
2197                         for (int is = 0; is < iSwings; is++)
2198                         {
2199                                                     *cb++ = m_SwathData[k][j][i+is]   & mask;
2200                         }
2201                                                 mask = ~mask;
2202                                         }
2203
2204                                         count++;
2205                                         if (count == n)
2206                                         {
2207                                                 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2208                                                 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2209                                                 cb = m_szCompressBuf+16;
2210                                                 count = 0;
2211                                                 ERRCHECK;
2212                                         }
2213                                 }
2214                                 mask = csavMask;
2215                                 for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
2216                                 {
2217                     for (int is = 0; is < iSwings; is++)
2218                     {
2219                                             *cb++ = m_SwathData[0][j][i + is]   & mask;
2220                     }
2221                                         mask = ~mask;
2222                                 }
2223                                 for (j = iStartRaster; j < iOffset; j += jDelta)
2224                                 {
2225                     for (int is = 0; is < iSwings; is++)
2226                     {
2227                                             *cb++ = m_SwathData[0][j][i + is]   & mask;
2228                     }
2229                                         mask = ~mask;
2230                                 }
2231
2232                                 count++;
2233                                 if (count == n)
2234                                 {
2235                                         err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2236                                     memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2237                                         cb = m_szCompressBuf+16;
2238                                         count = 0;
2239                                         ERRCHECK;
2240                                 }
2241                 i = i + delta;
2242             }
2243             if (count != 0)
2244             {
2245                 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2246                 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2247                 cb = m_szCompressBuf+16;
2248                 count = 0;
2249                 ERRCHECK;
2250             }
2251
2252             if (m_bBidirectionalPrintingOn)
2253                 m_cPrintDirection = (m_cPrintDirection + 1) % 2;
2254
2255             if (pPrinterXBow->m_iLdlVersion == 2) // Collie
2256             {
2257                 break;
2258             }
2259             LeftEdge += 2;
2260             RightEdge += 2;
2261
2262         }   // 1200 dpi split into two - end of for ib = 0 loop
2263
2264     }
2265
2266 /*
2267  *  Color Swath
2268  */
2269     if (!bPhotoPresent && bColorPresent)
2270     {
2271         iColors = 3;
2272         LastColor = 4;
2273         StartColor = 1;
2274         if (!bBlackPresent)
2275         {
2276             StartColor = 0;
2277             LastColor  = 3;
2278         }
2279         if (pPrinterXBow->m_iLdlVersion == 1)
2280         {
2281             // 1200 dpi split into two
2282             size = GetSwathWidth (StartColor, LastColor, iCurRasterSize/* * m_iBitDepth*/);
2283         }
2284         else
2285         {
2286             size = GetSwathWidth (StartColor, LastColor, iCurRasterSize * m_iBitDepth);
2287         }
2288         sColorSize = size;
2289     }
2290 /*
2291  *  Check if RefCount is close to overflow of 65k.
2292  */
2293
2294     if (!bPhotoPresent && bColorPresent && size)
2295     {
2296         if (size % iSwings)
2297             size = ((size / iSwings) + 1) * iSwings;
2298
2299         if (pPrinterXBow->m_iLdlVersion == 1)
2300         {
2301             RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2302                                     (DEVUNITS_XBOW / 600);
2303         }
2304         else
2305         {
2306             RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2307                                     (DEVUNITS_XBOW / (600 * m_iBitDepth));
2308         }
2309         Int16   sLastNozzle;
2310         Int16   sFirstNozzle = 1;
2311         unsigned int    uSweepSize;
2312         int     jDelta = m_iYResolution / pPrinterXBow->m_iColorPenResolution;
2313         jDelta *= m_iBitDepth;
2314
2315         uiSwathSize = size * iColors * sCurSwathHeight / jDelta;
2316
2317         uSweepSize = sCurSwathHeight * iSwings / jDelta;
2318         n = LDL_MAX_IMAGE_SIZE / (uSweepSize);
2319         count = 0;
2320
2321         if (m_iBitDepth == 2)
2322         {
2323             iStartRaster = (4 - (iStartRaster+1)) % 4;
2324             if (pPrinterXBow->m_iLdlVersion == 2)
2325             {
2326                 iStartRaster = m_cPassNumber % (m_iBitDepth);
2327             }
2328         }
2329
2330         sLastNozzle = sFirstNozzle - 1 + sCurSwathHeight / jDelta;
2331
2332         BYTE *cb = m_szCompressBuf + 16;    // load sweep command
2333         memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2334
2335
2336                 // 1200 dpi split into two
2337         int    ib = 0;
2338
2339         if (m_iYResolution > 300 && m_cPrintQuality != QUALITY_DRAFT)
2340         {
2341             iOffset = (sCurSwathHeight / (4 * m_iBitDepth));
2342             iOffset = iOffset + iOffset * ((m_cPassNumber) % (4 * m_iBitDepth));
2343         }
2344
2345         for (ib = 0; ib < (int) m_iBitDepth; ib++)
2346         {
2347             if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
2348             {
2349                 start = size - iSwings;
2350                 delta = -iSwings;
2351             }
2352             else
2353             {
2354                 start = 0;
2355                 delta = iSwings;
2356             }
2357             err = PrintSweep (uiSwathSize, bColorPresent, FALSE, FALSE,
2358                               iVertPosn, LeftEdge, RightEdge, m_cPrintDirection,
2359                               sFirstNozzle, sLastNozzle);
2360             ERRCHECK;
2361
2362             i = start + ib * m_iImageWidth;     // 1200 dpi split into two
2363             for (int l = 0; l < size; l += iSwings)   // Collie
2364             {
2365                 for (int k = StartColor; k < LastColor; k++)
2366                 {
2367                     mask = csavMask;
2368                     for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
2369                     {
2370                         for (int is = 0; is < iSwings; is++)
2371                         {
2372                             *cb++ = m_SwathData[k][j][i + is]   & mask;
2373                         }
2374                         mask = ~mask;
2375                     }
2376                     for (j = iStartRaster; j < iOffset; j += jDelta)
2377                     {
2378                         for (int is = 0; is < iSwings; is++)
2379                         {
2380                             *cb++ = m_SwathData[k][j][i + is]   & mask;
2381                         }
2382                         mask = ~mask;
2383                     }
2384
2385                     count++;
2386                     if (count == n)
2387                     {
2388                         err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2389                         memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2390
2391                         cb = m_szCompressBuf+16;
2392                         count = 0;
2393                         ERRCHECK;
2394                     }
2395
2396                 }
2397                 i = i + delta;
2398
2399             }
2400             if (count != 0)
2401             {
2402                 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2403                 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2404
2405                 cb = m_szCompressBuf+16;
2406                 count = 0;
2407                 ERRCHECK;
2408             }
2409
2410             LeftEdge += 2;
2411             RightEdge += 2;
2412
2413             if (m_bBidirectionalPrintingOn)
2414                 m_cPrintDirection = (m_cPrintDirection + 1) % 2;
2415             if (pPrinterXBow->m_iLdlVersion == 2) // Collie
2416             {
2417                 break;
2418             }
2419
2420         }   // 1200 dpi split into two - end of for ib = 0 loop
2421     }
2422
2423 /*
2424  *  Black Swath
2425  */
2426
2427     size = 0;
2428     if (bBlackPresent)
2429         size = GetSwathWidth (0, 1, iCurRasterSize);
2430
2431     if (size % iSwings)
2432             size = ((size/iSwings) + 1) * iSwings;
2433
2434     RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) * DEVUNITS_XBOW/600;
2435         
2436     if (bBlackPresent && size && m_iBitDepth != 2 &&
2437         ((m_cPassNumber % 2) == 0 || m_cPrintQuality == QUALITY_DRAFT))
2438     {
2439         Int16   sLastNozzle = 0;
2440         Int16   sFirstNozzle = 1;
2441
2442         int     xDelta = 0;
2443         BYTE    cVertAlign = 0;
2444
2445         if (bColorPresent)
2446         {
2447             cVertAlign = m_cKtoCVertAlign;
2448         }
2449
2450         if (bColorPresent && sColorSize && m_bBidirectionalPrintingOn)
2451             m_cPrintDirection = PRNDRN_RIGHTTOLEFT;
2452         if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
2453         {
2454             start = size - iSwings;
2455             delta = -iSwings;
2456         }
2457         else
2458         {
2459             start = 0;
2460             delta = iSwings;
2461         }
2462         if (m_iYResolution == 300)
2463             xDelta = iSwings;
2464         uiSwathSize = ((size/iSwings) * sCurSwathHeight * iSwings * (600 * m_iBitDepth)/ m_iYResolution);
2465
2466         if (pPrinterXBow->m_iLdlVersion == 2 && m_iNumColors != 1)
2467         {
2468             sFirstNozzle = 9;
2469         }
2470
2471                 err = PrintSweep (uiSwathSize, FALSE, bBlackPresent, FALSE,
2472                                                   (iVertPosn + cVertAlign), LeftEdge, RightEdge, m_cPrintDirection, sFirstNozzle, sLastNozzle);
2473
2474         ERRCHECK;
2475
2476         i = start;
2477         BYTE *cb = m_szCompressBuf+16;
2478         memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2479
2480         n = LDL_MAX_IMAGE_SIZE / (sCurSwathHeight * iSwings * 600 / m_iYResolution);
2481         count = 0;
2482
2483         iOffset = 0;
2484         if (m_iYResolution > 300 && m_cPrintQuality != QUALITY_DRAFT)
2485         {
2486             iOffset = sCurSwathHeight / 4;
2487             iOffset = iOffset + iOffset * (m_cPassNumber % 4);
2488         }
2489
2490         for (int l = 0; l < size; l += iSwings) // Collie
2491         {
2492             for (j = iOffset; j < sCurSwathHeight; j++)
2493             {
2494                 for (int is = 0; is < iSwings; is++)
2495                 {
2496                     *cb++ = m_SwathData[0][j][i + is]   & mask;
2497                 }
2498                 cb += xDelta;
2499             }
2500             for (j = 0; j < iOffset; j++)
2501             {
2502                 for (int is = 0; is < iSwings; is++)
2503                 {
2504                     *cb++ = m_SwathData[0][j][i + is]   & mask;
2505                 }
2506                 cb += xDelta;
2507             }
2508
2509             count++;
2510             if (count == n)
2511             {
2512                 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2513                 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2514
2515                 cb = m_szCompressBuf+16;
2516                 count = 0;
2517                 ERRCHECK;
2518             }
2519             i = i + delta;
2520         }
2521         if (count != 0)
2522         {
2523             err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2524             memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2525
2526             cb = m_szCompressBuf+16;
2527             count = 0;
2528             ERRCHECK;
2529         }
2530
2531                 if (m_bBidirectionalPrintingOn)
2532                         m_cPrintDirection = (m_cPrintDirection + 1) % 2;
2533     }
2534
2535     m_iRasterCount = 0;
2536
2537     if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
2538     {
2539         m_cPassNumber = (m_cPassNumber + 1) % (4 * m_iBitDepth);
2540         m_iVertPosn += ((((sCurSwathHeight/(4 * m_iBitDepth))) * 600 / m_iYResolution) * DEVUNITS_XBOW / 600) / m_iBitDepth;
2541                 if (m_iBitDepth == 1)
2542         {
2543             if (m_cPassNumber % 2)
2544                 m_iVertPosn += 4;
2545             else
2546                 m_iVertPosn -= 4;
2547         }
2548         else
2549         {
2550             m_iVertPosn -= 2;
2551             if ((m_cPassNumber % 4) == 0)
2552                   m_iVertPosn += (DEVUNITS_XBOW / pPrinterXBow->m_iColorPenResolution);
2553         }
2554         m_iRasterCount = (sCurSwathHeight - sCurSwathHeight / (4 * m_iBitDepth)) * m_iNumColors;
2555     }
2556     else
2557     {
2558         m_iVertPosn += ((sCurSwathHeight * 4 * 600) / m_iYResolution);
2559
2560     }
2561
2562     return err;
2563 }
2564
2565 void    LDLEncap::FillLidilHeader (void *pLidilHdr, int Command,
2566                                    UInt16 CmdLen, UInt16 DataLen = 0)
2567 {
2568
2569     int index = 1;
2570     m_szCmdBuf[0] = FRAME_SYN;
2571     WRITE16 (CmdLen);
2572     m_szCmdBuf[5] = (BYTE) Command;
2573     index = 6;
2574     WRITE16(m_sRefCount++);
2575     index = 8;
2576     WRITE16 (DataLen);
2577
2578 }
2579
2580 DRIVER_ERROR LDLEncap::PrintSweep (UInt32 SweepSize,
2581                            BOOL ColorPresent,
2582                            BOOL BlackPresent,
2583                                                    BOOL PhotoPresent,
2584                            Int32 VerticalPosition,
2585                            Int32 LeftEdge,
2586                            Int32 RightEdge,
2587                            char PrintDirection,
2588                            Int16 sFirstNozzle,
2589                            Int16 sLastNozzle)
2590 {
2591     // determine how many colors will be generated
2592     UInt16 colorcount = 0;
2593     UInt32  uiAffectedColors = 0;
2594     if (ColorPresent == TRUE) colorcount += 3;
2595     if (BlackPresent == TRUE) colorcount++;
2596         if (PhotoPresent == TRUE) 
2597         {
2598                 if (ColorPresent == FALSE)
2599                         colorcount++;
2600                 else
2601                         colorcount+=3;
2602         }
2603
2604     UInt16  mem_needed;
2605     if (pPrinterXBow->m_iLdlVersion == 1)
2606     {
2607         mem_needed =   SIZEOF_LDLHDR
2608                          + SIZEOF_LDL_PRTSWP_CMDOPT
2609                          + SIZEOF_LDL_PRTSWP_OPTFLDS
2610                          + SIZEOF_LDL_PRTSWP_COLROPT * colorcount
2611                          + SIZEOF_LDLTERM;
2612     
2613         if (colorcount != 0)
2614             mem_needed += SIZEOF_LDL_COLROPT_ACTIVECOLR;
2615     }
2616     else
2617     {
2618         mem_needed =   SIZEOF_LDLHDR
2619                          + SIZEOF_LDL_PRTSWP_CMDOPT + 7
2620                          + SIZEOF_LDL_PRTSWP_OPTFLDS
2621                          + SIZEOF_LDL_PRTSWP_COLROPT + 4
2622                          + SIZEOF_LDLTERM;
2623     }
2624
2625     memset (m_szCmdBuf, 0, mem_needed);
2626
2627     FillLidilHeader (NULL, eLDLPrintSweep, mem_needed);
2628
2629     int     index = SIZEOF_LDLHDR;
2630     if (pPrinterXBow->m_iLdlVersion == 2)
2631     {
2632         m_szCmdBuf[index++] = 1;    // Version number
2633     }
2634     WRITE32 (SweepSize);
2635     WRITE32 (VerticalPosition);
2636     WRITE32 (m_iLeftMargin);
2637     if (pPrinterXBow->m_iLdlVersion == 1)
2638     {
2639         // LIDIL First Version
2640         m_szCmdBuf[index++] = SWINGFMT_UNCOMPRSS;
2641     }
2642     else
2643     {
2644         // LIDIL Second Version
2645         m_szCmdBuf[index++] = 1;
2646     }
2647     m_szCmdBuf[index++] = PrintDirection;
2648     if (pPrinterXBow->m_iLdlVersion == 2)
2649     {
2650         WRITE32 (0); // Shingle mask
2651     }
2652     WRITE32 (IPS_CARRSPEED|IPS_INIPRNSPEED|ACCURATEPOSN_NEEDED);
2653  // Carriage Speed - 25 for plain, 12 for photo
2654     if (m_cPrintQuality == QUALITY_BEST && m_cMediaType == MEDIA_PHOTO)
2655         m_szCmdBuf[index++] = 12;
2656     else
2657         m_szCmdBuf[index++] = 25;
2658     m_szCmdBuf[index++] = 4; // Initial Print Speed
2659     m_szCmdBuf[index++] = 1; // Need Accurate Position
2660     if (pPrinterXBow->m_iLdlVersion == 2)
2661     {
2662         m_szCmdBuf[index++] = 1; // Number of entries in the sweep
2663     }
2664
2665     // fill in the color information
2666     if(colorcount == 0)
2667     {
2668         m_szCmdBuf[index++] = NO_ACTIVE_COLORS;
2669         m_szCmdBuf[index++] = FRAME_SYN;
2670         mem_needed = index;
2671     }
2672     else
2673     {
2674         // figure out what are the active colors and fill in the optional color fields.
2675
2676         UInt16 colrpresent = 0;
2677         UInt16 colr_found=0;
2678         UInt16 colormask = 0x01;
2679         UInt16 offset = eLDLBlack;
2680         UInt16 iDataRes;
2681         UInt16 iPrintRes;
2682         uiAffectedColors = offset;
2683         if (BlackPresent == TRUE)
2684         {
2685             uiAffectedColors = 0x1;
2686         }
2687         if(BlackPresent == FALSE && PhotoPresent == FALSE)
2688         {
2689             offset = eLDLCyan;
2690             colormask=0x02;
2691             uiAffectedColors |= 0x0000000e;
2692         }
2693         else if (BlackPresent == FALSE && PhotoPresent == TRUE)
2694         {
2695                         if (ColorPresent == TRUE)
2696                         {
2697                                 offset = eLDLCyan;
2698                                 colormask=0x02;
2699                 uiAffectedColors |= 0x0000007e;
2700                         }
2701                         else
2702                         {
2703                                 offset = eLDLLoBlack;
2704                                 colormask=0x40;
2705                 uiAffectedColors |= 0x00000070;
2706                         }
2707         }
2708
2709         int actv_colr_index = index;
2710         int iColorRes = 300;
2711         if (pPrinterXBow->m_iLdlVersion == 1)
2712         {
2713             index += 2;
2714         }
2715         else
2716         {
2717             iColorRes = 600;
2718         }
2719         for(UInt16 i = offset; colr_found < colorcount && i < eLDLMaxColor; i++)
2720         {
2721             colr_found++;
2722             colrpresent = colrpresent | colormask;
2723
2724             if (pPrinterXBow->m_iLdlVersion == 2)
2725             {
2726                 WRITE32 (uiAffectedColors);
2727             }
2728             WRITE32 (LeftEdge);
2729             WRITE32 (RightEdge);
2730             WRITE32 (LeftEdge);
2731             WRITE32 (RightEdge);
2732
2733             if ((i == 0 && pPrinterXBow->m_iLdlVersion == 1) || (BlackPresent && pPrinterXBow->m_iLdlVersion == 2))
2734             {
2735                 iDataRes = 600;
2736                 iPrintRes = pPrinterXBow->m_iBlackPenResolution;
2737             }
2738             else
2739             {
2740                 iDataRes  = iColorRes; // 300;
2741                 iPrintRes = iColorRes; // 300;
2742             }
2743             WRITE16 (iDataRes);         // Vertical Data Resolution
2744             WRITE16 (iPrintRes);        // Vertical Print Resolution
2745
2746             if (pPrinterXBow->m_iLdlVersion == 2)
2747             {
2748                 WRITE16 (m_iXResolution * m_iBitDepth);   // Horizontal Data Resolution // Collie
2749             }
2750             else
2751             {
2752                 WRITE16 (m_iXResolution);
2753             }
2754
2755                         if (m_iXResolution == 300)
2756                         {
2757                                 WRITE16 (600);   // Force 2 drop for draft mode.
2758                         }
2759             else
2760                         {
2761                 if (pPrinterXBow->m_iLdlVersion == 2)
2762                 {
2763                                     WRITE16 (m_iXResolution * m_iBitDepth);   // Horizontal Print Resolution // Collie
2764                 }
2765                 else
2766                 {
2767                     WRITE16 (m_iXResolution);
2768                 }
2769                         }
2770             WRITE16 (sFirstNozzle);
2771             if (sLastNozzle == 0)
2772             {
2773                 int     iTmp = m_iRasterCount / m_iNumColors;
2774                 if (pPrinterXBow->m_iLdlVersion == 2)
2775                 {
2776                     WRITE16 (sFirstNozzle - 1 + ((iTmp * iPrintRes) / (m_iYResolution * m_iBitDepth))); // Collie
2777                 }
2778                 else
2779                 {
2780                     WRITE16 (sFirstNozzle - 1 + ((iTmp * iPrintRes) / (m_iYResolution)))
2781                 }
2782             }
2783             else
2784             {
2785                 WRITE16 (sLastNozzle);
2786             }
2787
2788             m_szCmdBuf[index++] = 0;    // Vertical Alignment
2789             colormask = colormask << 1;
2790             if (pPrinterXBow->m_iLdlVersion == 2)
2791             {
2792                 break;
2793             }
2794
2795         }
2796         // write the active color field
2797         mem_needed = index;
2798         if (pPrinterXBow->m_iLdlVersion == 1)
2799         {
2800             index = actv_colr_index;
2801             WRITE16 (colrpresent);
2802             index = mem_needed;
2803         }
2804
2805         if (pPrinterXBow->m_iLdlVersion == 2)
2806         {
2807             m_szCmdBuf[index++] = 0; // # of entries in the shingle array
2808         }
2809         m_szCmdBuf[index++] = FRAME_SYN;
2810         mem_needed = index;
2811     }
2812
2813     // write out the data
2814     return (pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed));
2815 }
2816
2817
2818 DRIVER_ERROR LDLEncap::LoadSweepData (BYTE *imagedata, int imagesize)
2819 {
2820     UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_LDSWPDATA_CMDOPT
2821                                       + SIZEOF_LDLTERM;
2822     UInt16 diff=0;
2823     if(mem_needed < LDLPACKET_MINSIZE)
2824     {
2825         diff = LDLPACKET_MINSIZE - mem_needed;
2826         mem_needed = LDLPACKET_MINSIZE;
2827     }
2828     memset (m_szCmdBuf, 0, mem_needed);
2829
2830     BYTE    *compressed_dataptr = imagedata;
2831     UInt16  compressed_size = imagesize;
2832
2833 #ifdef  APDK_LDL_COMPRESS
2834     if (m_ldlCompressData)
2835     {
2836             m_ldlCompressData->Init ((UInt16 *) (imagedata+16), imagesize);
2837             CompressData ();
2838             GetFrameInfo (&compressed_dataptr, &compressed_size);
2839     }
2840 #endif
2841
2842     FillLidilHeader (NULL, eLDLLoadSweepData, mem_needed, compressed_size);
2843
2844     int     index = SIZEOF_LDLHDR;
2845     WRITE16 (imagesize);
2846
2847     if(diff)
2848     {
2849         memset (m_szCmdBuf+index, 0xFF, diff);
2850         index += diff;
2851     }
2852     m_szCmdBuf[index++] = FRAME_SYN;
2853
2854     memcpy (compressed_dataptr, m_szCmdBuf, 16);
2855     return (pPrinterXBow->Send (compressed_dataptr, (DWORD) compressed_size+16));
2856 }
2857
2858 LDLEncap::~LDLEncap ()
2859 {
2860     if (m_SwathData)
2861         // Camera change - allocation is now AllocMem instead of new
2862         //        delete [] (BYTE *) m_SwathData;
2863         m_pSys->FreeMem ((BYTE *) m_SwathData);
2864     if (m_szCmdBuf)
2865         delete [] m_szCmdBuf;
2866     if (m_szCompressBuf)
2867         delete [] m_szCompressBuf;
2868     if (piCreditCount)
2869         m_pSys->FreeMem ((BYTE *) piCreditCount);
2870     if (m_pbyPacketBuff)
2871         m_pSys->FreeMem ((BYTE *) m_pbyPacketBuff);
2872     if (pbySync)
2873         m_pSys->FreeMem ((BYTE *) pbySync);
2874 #ifdef  APDK_LDL_COMPRESS
2875     if (m_ldlCompressData)
2876     {
2877         delete m_ldlCompressData;
2878         m_ldlCompressData = NULL;
2879     }
2880 #endif
2881 }
2882
2883 DRIVER_ERROR LDLEncap::StartJob ()
2884 {
2885     DRIVER_ERROR err = NO_ERROR;
2886     BYTE *pby = NULL;
2887     BYTE by = 0;
2888     BOOL bCreditInitialized = FALSE;
2889     WORD wCreditWaitCount = 0;
2890
2891     // Send Sync packet
2892     err = pPrinterXBow->Send (pbySync, (DWORD) SYNCSIZE);
2893     if(err)
2894     {
2895         return err;
2896     }
2897
2898     // Send Sync Complete packet
2899     err = pPrinterXBow->Send (bySyncComplete, (DWORD) sizeof (bySyncComplete));
2900     if(err)
2901     {
2902         return err;
2903     }
2904
2905     // Send Reset LIDIL packet
2906     err = pPrinterXBow->Send (byResetLIDIL, (DWORD) sizeof (byResetLIDIL));
2907     if(err)
2908     {
2909         return err;
2910     }
2911
2912     if (pPrinterXBow->IOMode.bDevID)
2913     {
2914         // Enable pacing, get credit packet and update credit count
2915         err = pPrinterXBow->Send (byEnablePacing, (DWORD) sizeof (byEnablePacing));
2916         if (err)
2917         {
2918             return err;
2919         }
2920
2921         while (!bCreditInitialized && wCreditWaitCount++ < CREDIT_WAIT)
2922         {
2923             bCreditInitialized = UpdateState (TRUE);
2924         }
2925
2926         if (!bCreditInitialized)
2927         {
2928             return SYSTEM_ERROR;
2929         }
2930         else
2931         {
2932             // Send Enable On Change status packet.  We don't have to worry about flushing the buffer,
2933             // because the ::Send logic will do that for us.  If we run out of credit for a command, the
2934             // first thing that we do is flush the buffer.  If we haven't already sent the EOCQuery, it
2935             // will get sent then.
2936             err = pPrinterXBow->Send (byEOCStatusQuery, (DWORD) sizeof (byEOCStatusQuery));
2937             if (err)
2938             {
2939                 return err;
2940             }
2941         }
2942
2943         // Setup Cancel command.  It would be nice to do this in the LDLEncap constructor, but we have
2944         // to know the JobID before we can setup the cancel command.
2945         memcpy (pbyCancel, byPrepareToCancel, sizeof (byPrepareToCancel));
2946         pbyCancel[COMMAND_NUMBER_BYTE] = 0x00;
2947         pbyCancel[COMMAND_OPT_BYTE] = 0x02;
2948
2949         pby = (BYTE*) &pPrinterXBow->pLDLEncap;
2950         if(m_bLittleEndian)
2951         {
2952             // Go to last byte of pLDLEncap in memory, since system is little endian
2953             pby += sizeof (pPrinterXBow->pLDLEncap) - 1;
2954         }
2955
2956         for(by = 0; by < sizeof(pPrinterXBow->pLDLEncap); by++)
2957         {
2958             if(m_bLittleEndian)
2959                 pbyCancel[by + COMMAND_OPT_BYTE + 1] = *pby--;
2960             else
2961                 pbyCancel[by + COMMAND_OPT_BYTE + 1] = *pby++;
2962         }
2963
2964         // Setup Query command
2965 //        memcpy(byQuery, byEnableResponses, sizeof(byEnableResponses));
2966 //        memcpy(byQuery + sizeof(byEnableResponses), byStatusQuery, sizeof(byStatusQuery));
2967 //        memcpy(byQuery + (sizeof(byEnableResponses) + sizeof(byStatusQuery)),
2968 //               byDisableResponses, sizeof(byDisableResponses));
2969     }
2970
2971     UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT + SIZEOF_LDLTERM;
2972     if (pPrinterXBow->m_iLdlVersion == 2)
2973     {
2974         mem_needed += 4;
2975     }
2976
2977     FillLidilHeader (NULL, eLDLStartJob, mem_needed);
2978
2979     // write in the job id
2980     int     index = SIZEOF_LDLHDR;
2981     m_szCmdBuf[index++] = OPERATION_STJOB;
2982     if (pPrinterXBow->IOMode.bDevID)
2983     {
2984         WRITE32 ((UInt32) this);
2985     }
2986     else
2987     {
2988         WRITE32 ((UInt32) 0xbadfad);    // for deterministic testing, des
2989     }
2990
2991     if (pPrinterXBow->m_iLdlVersion == 2)
2992     {
2993         WRITE32 (0);    // Shingle Mask option
2994     }
2995
2996     // add in sync frame.
2997     m_szCmdBuf[index++] = FRAME_SYN;
2998
2999     // fill in the job header and write out the generated data
3000     err = pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3001     ERRCHECK;
3002
3003     err = StartPage ();
3004     ERRCHECK;
3005
3006 #if 0
3007         /*
3008          *  Query printer if pens are aligned when both pens are present.
3009          *  If so, set Bi-Directional printing on.
3010          *  If m_bBierectionalPrintingOn is already set or current mode is
3011          *  PhotoBest, don't query for pen alignment.
3012          */
3013     if (m_bBidirectionalPrintingOn || m_cPrintQuality == QUALITY_NORMAL)
3014         return NO_ERROR;
3015
3016     mem_needed = SIZEOF_LDLHDR + 2 + SIZEOF_LDLTERM;
3017     memset (m_szCmdBuf, 0, LDLPACKET_MINSIZE);
3018     for (index = mem_needed; index < LDLPACKET_MINSIZE; index++)
3019         m_szCmdBuf[index] = 0xFF;
3020     if (mem_needed < LDLPACKET_MINSIZE)
3021         mem_needed = LDLPACKET_MINSIZE;
3022     FillLidilHeader (NULL, eLDLQueryPrinter, mem_needed);
3023     index = SIZEOF_LDLHDR;
3024     m_szCmdBuf[index++] = 3;    // Pen Alignment   - is this the right command?
3025     m_szCmdBuf[index++] = 0;    // Query - Immediate response
3026     m_szCmdBuf[mem_needed-1] = FRAME_SYN;
3027     pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3028
3029     index = 0;
3030     if ((pSS->FromDevice ((char *) m_szCmdBuf, (WORD *) &index)) == NO_ERROR)
3031     {
3032 //      what am I looking for here?
3033         index = SIZEOF_LDLHDR + 1;
3034 //      2 bytes for color alignment, however, bits 7-15 are not used at present
3035         BYTE    bColor = m_szCmdBuf[index] & 0x7F;
3036         if ((bColor & 0x0F) == 0x0F ||      // bits 0 - 3 represent KCMY
3037             (bColor & 0x7E) == 0x7E)        // bits 4 - 6 represent cmk
3038             m_bBidirectionalPrintingOn = TRUE;
3039     }
3040 #endif
3041
3042     return err;
3043 }
3044
3045
3046 DRIVER_ERROR    LDLEncap::EndJob ()
3047 {
3048     DRIVER_ERROR err = NO_ERROR;
3049
3050     UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT + SIZEOF_LDLTERM;
3051
3052     FillLidilHeader (NULL, eLDLEndJob, mem_needed);
3053
3054     int     index = SIZEOF_LDLHDR;
3055     m_szCmdBuf[index++] = OPERATION_ENDJOB;
3056     if (pPrinterXBow->IOMode.bDevID)
3057     {
3058         WRITE32 ((UInt32) this);
3059     }
3060     else
3061     {
3062         WRITE32 ((UInt32) 0xbadfad);    // for deterministic testing, des
3063     }
3064
3065     m_szCmdBuf[index++] = FRAME_SYN;
3066
3067     err = pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3068     if(err)
3069     {
3070         return err;
3071     }
3072
3073     // Send Sync packet
3074     err = pPrinterXBow->Send (pbySync, SYNCSIZE);
3075     if(err)
3076     {
3077         return err;
3078     }
3079
3080     // Send Sync Complete packet
3081     err = pPrinterXBow->Send (bySyncComplete, (DWORD) sizeof (bySyncComplete));
3082     if(err)
3083     {
3084         return err;
3085     }
3086
3087     // Send Reset LIDIL packet
3088     err = pPrinterXBow->Send (byResetLIDIL, (DWORD) sizeof (byResetLIDIL));
3089     if(err)
3090     {
3091         return err;
3092     }
3093
3094     return NO_ERROR;
3095 }
3096
3097 DRIVER_ERROR LDLEncap::StartPage ()
3098 {
3099
3100     //figure out how much memory we needed
3101     UInt16 colorcount = 0; //m_iNumColors;
3102     UInt32 mem_needed = SIZEOF_LDLHDR  + SIZEOF_LDL_LDPAGE_CMDOPT
3103                                        + SIZEOF_LDL_LDPAGE_OPTFLDS
3104                                        + SIZEOF_LDLTERM;
3105
3106     memset (m_szCmdBuf, 0, mem_needed);
3107
3108     FillLidilHeader (NULL, eLDLLoadPage, (UInt16) mem_needed);
3109
3110     char    mediatype = MEDIATYPE_PLAIN;
3111     BYTE    quality   = (BYTE) QUALITYLEVEL_NORMAL;
3112     if (m_cPrintQuality == QUALITY_BEST && m_cMediaType == MEDIA_PHOTO)
3113     {
3114         mediatype = MEDIATYPE_PHOTO;
3115         quality   = (BYTE) QUALITYLEVEL_BEST;
3116     }
3117     else if (m_cPrintQuality == QUALITY_DRAFT)
3118         quality = (BYTE) QUALITYLEVEL_DRAFT;
3119
3120     int     index = SIZEOF_LDLHDR;
3121     m_szCmdBuf[index++] = mediatype;
3122     m_szCmdBuf[index++] = MEDIASRC_MAINTRAY;
3123     m_szCmdBuf[index++] = MEDIADEST_MAINBIN;
3124     m_szCmdBuf[index++] = quality; //PrintQuality;
3125     m_szCmdBuf[index++] = SPECLOAD_NONE;
3126
3127     Int32   iVal;
3128     iVal = (Int32) (m_pthisPC->PhysicalPageSizeX () * 1000);
3129     WRITE32 ((iVal * DEVUNITS_XBOW) / 1000);
3130     iVal = (Int32) (m_pthisPC->PhysicalPageSizeY () * 1000);
3131     WRITE32 ((iVal * DEVUNITS_XBOW) / 1000);
3132
3133     WRITE32 (MEDIALD_SPEED|NEED_TO_SERVICE_PERIOD|MINTIME_BTW_SWEEP);
3134
3135     // set up the option fields
3136     m_szCmdBuf[index++] = 4; // MediaLoadSpeed;
3137     m_szCmdBuf[index++] = 0; // NeedToServicePeriod;
3138     WRITE16 (200);           // MinTimeBetweenSweeps
3139
3140     if (colorcount == 0)
3141     {
3142         m_szCmdBuf[index++] = FRAME_SYN;
3143     }
3144
3145     m_bStartPageNotSent = FALSE;
3146     // write out the data
3147     return (pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed));
3148 }
3149
3150 DRIVER_ERROR LDLEncap::Continue ()
3151 {
3152
3153     UInt16 mem_needed = SIZEOF_LDLHDR + 1
3154                         + SIZEOF_LDLTERM;
3155     int     index;
3156     memset (m_szCmdBuf, 0, LDLPACKET_MINSIZE);
3157     for (index = mem_needed; index < LDLPACKET_MINSIZE; index++)
3158         m_szCmdBuf[index] = 0xFF;
3159     if (mem_needed < LDLPACKET_MINSIZE)
3160         mem_needed = LDLPACKET_MINSIZE;
3161     FillLidilHeader (NULL, eLDLControl, mem_needed);
3162     index = SIZEOF_LDLHDR;
3163     m_szCmdBuf[index] = OPERATION_CONTINUE;
3164     m_szCmdBuf[mem_needed-1] = FRAME_SYN;
3165     return (pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed));
3166 }
3167
3168 void LDLEncap::Cancel ()
3169 {
3170
3171     UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT
3172                         + SIZEOF_LDLTERM;
3173     int     index;
3174     memset (m_szCmdBuf, 0, LDLPACKET_MINSIZE);
3175     for (index = mem_needed; index < LDLPACKET_MINSIZE; index++)
3176         m_szCmdBuf[index] = 0xFF;
3177     if (mem_needed < LDLPACKET_MINSIZE)
3178         mem_needed = LDLPACKET_MINSIZE;
3179     FillLidilHeader (NULL, eLDLControl, mem_needed);
3180     index = SIZEOF_LDLHDR;
3181     WRITE32 ((UInt32) this);
3182     m_szCmdBuf[index] = OPERATION_CANCJOB;
3183     m_szCmdBuf[mem_needed-1] = FRAME_SYN;
3184     pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3185 }
3186
3187 DRIVER_ERROR LDLEncap::CleanPen ()
3188 {
3189
3190     UInt16 mem_needed = SIZEOF_LDLHDR + 1 + 2
3191                         + SIZEOF_LDLTERM;
3192     int     index;
3193     short   sNumSpits = 32;
3194     memset (m_szCmdBuf, 0, LDLPACKET_MINSIZE);
3195     for (index = mem_needed; index < LDLPACKET_MINSIZE; index++)
3196         m_szCmdBuf[index] = 0xFF;
3197     if (mem_needed < LDLPACKET_MINSIZE)
3198         mem_needed = LDLPACKET_MINSIZE;
3199     FillLidilHeader (NULL, eLDLHandlePen, mem_needed);
3200     index = SIZEOF_LDLHDR;
3201     m_szCmdBuf[index++] = OPERATION_SPIT_PEN;
3202     WRITE16 (sNumSpits);
3203     m_szCmdBuf[mem_needed-1] = FRAME_SYN;
3204     pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3205
3206     return NO_ERROR;
3207 }
3208
3209 DRIVER_ERROR LDLEncap::EndPage ()
3210 {
3211
3212     DRIVER_ERROR    err = NO_ERROR;
3213     int icount = 0;
3214     int iCurNumRasters = m_iRasterCount;
3215     if ((m_cPrintQuality == QUALITY_DRAFT || m_iYResolution == 300) && m_iRasterCount)
3216         icount = 1;
3217     else if (m_cPrintQuality != QUALITY_DRAFT)
3218     {
3219         icount = 4 * m_iBitDepth;
3220         iCurNumRasters = m_sSwathHeight * m_iNumColors;
3221     }
3222
3223     int i, j, n;
3224     n = m_sSwathHeight / (4 * m_iBitDepth);
3225
3226     n = n * (m_cPassNumber + 1) - m_iNextRaster;
3227     for (i = 0; i < m_iNumColors; i++)
3228     {
3229         for (j = 0; j < n; j++)
3230             memset (m_SwathData[i][m_iNextRaster+j], 0, m_iImageWidth * m_iBitDepth);
3231     }
3232     m_iNextRaster += n;
3233     n = m_sSwathHeight / (4 * m_iBitDepth);
3234
3235     while (icount)
3236     {
3237         m_iRasterCount = iCurNumRasters;
3238         err = ProcessSwath (m_iImageWidth);
3239         if (err != NO_ERROR)
3240             break;
3241         icount--;
3242         if (m_iNextRaster >= m_sSwathHeight)
3243             m_iNextRaster = 0;
3244         for (i = 0; i < m_iNumColors; i++)
3245         {
3246             for (j = 0; j < n; j++)
3247                 memset (m_SwathData[i][m_iNextRaster+j], 0, m_iImageWidth * m_iBitDepth);
3248         }
3249         m_iNextRaster += n;
3250     }
3251
3252     UInt16 mem_needed = SIZEOF_LDLHDR
3253                         + SIZEOF_LDL_EJPAGE_CMDOPT
3254                         + SIZEOF_LDL_EJPAGE_OPTFLDS
3255                         + SIZEOF_LDLTERM;
3256
3257     memset (m_szCmdBuf, 0, mem_needed);
3258     FillLidilHeader(NULL, eLDLEjectPage, mem_needed);
3259
3260     int     index = SIZEOF_LDLHDR;
3261     WRITE32 (MEDIA_EJSPEED);
3262
3263     m_szCmdBuf[index++] = 15;
3264     m_szCmdBuf[index++] = FRAME_SYN;
3265
3266     if(err == NO_ERROR)
3267     {
3268         err = pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3269     }
3270
3271     m_sRefCount = 6;
3272     m_iBlankRasters = 0;
3273     m_iVertPosn = (int) (m_pthisPC->PrintableStartY () * DEVUNITS_XBOW);
3274     m_iRasterCount = 0;
3275     m_iNextRaster = 0;
3276     m_iNextColor  = 0;
3277
3278         float   fXOverSpray = 0.0;
3279     float   fYOverSpray = 0.0;
3280     float   fLeftOverSpray = 0.0;
3281     float   fTopOverSpray  = 0.0;
3282         FullbleedType   fbType;
3283     if (m_pthisPC->bDoFullBleed &&
3284         pPrinterXBow->FullBleedCapable (m_pthisPC->thePaperSize,
3285                                                                           &fbType,
3286                                       &fXOverSpray, &fYOverSpray,
3287                                       &fLeftOverSpray, &fTopOverSpray))
3288     {
3289
3290                 /*
3291                  *      To get the printer to do fullbleed printing, move the vertical postion 
3292                  *      to cover the overspary. Overspray is needed to take care of
3293                  *      skew during paper pick. These values may be mech dependent.
3294                  *      Currently, supported only on PhotoSmart 100, Malibu. DJ3600 supports
3295                  *      fullbleed printing also. The current values for overspray are
3296                  *      0.059 inch for top, bottom and left edges and 0.079 for right edge.
3297                  */
3298                 m_iVertPosn = (int) (-fTopOverSpray * DEVUNITS_XBOW);
3299     }
3300
3301     if (/*m_iYResolution != 300*/m_cPrintQuality != QUALITY_DRAFT)
3302         m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / 4) * m_iNumColors;
3303
3304     m_bStartPageNotSent = TRUE;
3305
3306     if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
3307     {
3308         m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * m_iNumColors;
3309         m_iVertPosn -= (((m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * 600 / m_iYResolution) * DEVUNITS_XBOW / 600);
3310     }
3311     m_cPassNumber = 0;
3312
3313     if (m_pthisPC->bDoFullBleed &&
3314         pPrinterXBow->FullBleedCapable (m_pthisPC->thePaperSize,
3315                                                                           &fbType,
3316                                       &fXOverSpray, &fYOverSpray,
3317                                       &fLeftOverSpray, &fTopOverSpray))
3318         {
3319                 if (m_iVertPosn < -850) m_iVertPosn = -850;
3320         }
3321         else
3322         {
3323                 if (m_iVertPosn < -600) m_iVertPosn = -600;
3324         }
3325     if (m_iBitDepth == 2)
3326         m_iVertPosn += 6;
3327
3328     for (i = 0; i < m_iNumColors; i++)
3329     {
3330         for (int j = 0; j < m_sSwathHeight; j++)
3331         {
3332             memset (m_SwathData[i][j], 0, m_iImageWidth);
3333         }
3334     }
3335
3336     return (err);
3337 }
3338
3339 // This routine dynamically allocates memory in which to read bytes from the port.  We allocate
3340 // memory in MAX_PACKET_READ_SIZE chunks, which we set in ldlencap.h to 256 bytes.  The minimum
3341 // read size is the size of a printer packet, which is 64 bytes.  We shouldn't have to read more
3342 // than 256 bytes from the port since we only are getting credit and status.  Developers may want
3343 // to increase or decrease the MAX_PACKET_READ_SIZE for their particular system based upon whether
3344 // memory is easier to get statically or dynamically.  For instance, a system with a lot of static
3345 // memory may want to increase MAX_PACKET_READ_SIZE to 4096 to minimize reads.  A system with
3346 // limited static memory may want to allocate memory in smaller chunks, so 256 may be better.  The
3347 // developer may reduce the MAX_PACKET_READ_SIZE to as little as 64 if desired, but it must always
3348 // be a multiple of 64.
3349
3350 /*
3351  *    Author: Don Castrapel
3352  */
3353
3354 BOOL LDLEncap::GetPackets(DWORD &dwBytesRead)
3355 {
3356     DRIVER_ERROR err = NO_ERROR;
3357     DWORD dwReadSize = 0;
3358     WORD wPacketWaitCount = 0;
3359     BYTE *pbyPacketBuff = NULL;
3360
3361     dwBytesRead = 0;
3362
3363     if(m_pbyPacketBuff)
3364     {
3365         // If we've had to reallocate the packet read buffer because it was too small to hold a read,
3366         // let's deallocate it and start with the original size.  This will prevent us hanging onto
3367         // what could be a large chunk of memory while also not performing multiple allocs and deallocs
3368         // in the normal case where the buffer holds the entire read
3369         if(m_dwPacketBuffSize != MAX_PACKET_READ_SIZE)
3370         {
3371             m_pSys->FreeMem ((BYTE *) m_pbyPacketBuff);
3372             m_pbyPacketBuff = NULL;
3373             m_dwPacketBuffSize = 0;
3374         }
3375         else
3376             memset(m_pbyPacketBuff, 0, MAX_PACKET_READ_SIZE);
3377     }
3378
3379     // Wait for packets
3380     while(!dwBytesRead && wPacketWaitCount++ < PACKET_WAIT)
3381     {
3382         if(m_pSys->BusyWait((DWORD)100) == JOB_CANCELED)
3383         {
3384             return FALSE;
3385         }
3386
3387         dwReadSize = MAX_PACKET_READ_SIZE;
3388
3389         do
3390         {
3391             // If we've done a read but it was not a multiple of MAX_PACKET_READ_SIZE, then we
3392             // didn't read the full request size last time.  That means that we read some bytes
3393             // but that the printer didn't have any more to send
3394             if(dwBytesRead % MAX_PACKET_READ_SIZE)
3395             {
3396                 break; // Out of do loop
3397             }
3398
3399             // FromDevice resets dwReadSize to the number of bytes read from the port
3400             dwReadSize = MAX_PACKET_READ_SIZE;
3401
3402             if(!m_pbyPacketBuff)
3403             {
3404                 // First read, allocate buffer to hold data
3405                 m_pbyPacketBuff = m_pSys->AllocMem(MAX_PACKET_READ_SIZE);
3406                 if(!m_pbyPacketBuff)
3407                 {
3408                     return FALSE;
3409                 }
3410                 memset(m_pbyPacketBuff, 0, MAX_PACKET_READ_SIZE);
3411                 m_dwPacketBuffSize = MAX_PACKET_READ_SIZE;
3412             }
3413             else if(dwBytesRead)
3414             {
3415                 // We've already read some bytes, so allocate a temporary buffer to store
3416                 // what we've read so far.  We'll copy what we've read into the temporary buffer,
3417                 // delete the original buffer, reallocate a new buffer MAX_PACKET_READ_SIZE
3418                 // bytes larger, read the temporary buffer back into the newly reallocated
3419                 // buffer, then delete the temporary buffer
3420                 pbyPacketBuff = m_pSys->AllocMem(dwBytesRead + MAX_PACKET_READ_SIZE);
3421                 if(!pbyPacketBuff)
3422                 {
3423                     return FALSE;
3424                 }
3425                 m_dwPacketBuffSize += MAX_PACKET_READ_SIZE;
3426                 memset(pbyPacketBuff, 0, m_dwPacketBuffSize);
3427
3428                 memcpy(pbyPacketBuff, m_pbyPacketBuff, dwBytesRead);
3429                 if(m_pbyPacketBuff)
3430                 {
3431                     m_pSys->FreeMem((BYTE *)m_pbyPacketBuff);
3432                     m_pbyPacketBuff = NULL;
3433                 }
3434
3435                 m_pbyPacketBuff = pbyPacketBuff;
3436             }
3437
3438             err = m_pSys->FromDevice((m_pbyPacketBuff + dwBytesRead), &dwReadSize);
3439             if(err)
3440             {
3441                 return FALSE;
3442             }
3443             dwBytesRead += dwReadSize;
3444         } while(!err && dwReadSize);
3445     } // while(!dwBytesRead && wPacketWaitCount++ < PACKET_WAIT)
3446
3447     if(!dwBytesRead)
3448     {
3449         // No data to read from port
3450         return FALSE;
3451     }
3452
3453     return TRUE;
3454 }
3455
3456 /*
3457  *    Author: Don Castrapel
3458  */
3459
3460 BOOL LDLEncap::UpdateState(BOOL bInitialize)
3461 {
3462 //    DRIVER_ERROR err = NO_ERROR;
3463     BOOL bPacketsReceived = FALSE;
3464     BOOL bUpdatedState = FALSE;
3465     BYTE byPacketType = 0;
3466     BYTE byCommandNumber = 0;
3467     WORD wCommandLength = 0;
3468     WORD wDataLength = 0;
3469     WORD wReferenceNumber = 0;
3470     DWORD dwBytesRead = 0;
3471     DWORD dwBytesProcessed = 0;
3472     BYTE by = 0;
3473
3474     // Read packets from port
3475     bPacketsReceived = GetPackets(dwBytesRead);
3476     if(!bPacketsReceived)
3477     {
3478         return FALSE;
3479     }
3480
3481     while(dwBytesProcessed < dwBytesRead)
3482     {
3483         if(m_pbyPacketBuff[dwBytesProcessed] != '$')
3484         {
3485             return FALSE;
3486         }
3487
3488         // Get packet type and command number, command length, data length
3489         byPacketType = m_pbyPacketBuff[PACKET_TYPE_BYTE + dwBytesProcessed];
3490         byCommandNumber = m_pbyPacketBuff[COMMAND_NUMBER_BYTE + dwBytesProcessed];
3491         wCommandLength = (m_pbyPacketBuff[COMMAND_LENGTH_BYTE + dwBytesProcessed] << 8) |
3492                           m_pbyPacketBuff[COMMAND_LENGTH_BYTE + 1 + dwBytesProcessed];
3493         wDataLength = (m_pbyPacketBuff[DATA_LENGTH_BYTE + dwBytesProcessed] << 8) |
3494                        m_pbyPacketBuff[DATA_LENGTH_BYTE + 1 + dwBytesProcessed];
3495         wReferenceNumber = (m_pbyPacketBuff[REFERENCE_NUMBER_BYTE + dwBytesProcessed] << 8) |
3496                             m_pbyPacketBuff[REFERENCE_NUMBER_BYTE + 1 + dwBytesProcessed];
3497
3498         // We should only get packet type 16 (Response, Command Executed), packet type
3499         // 24 (Response, Auto), packet type 32 (Absolute Credit) or packet type 33
3500         // (Incremental Credit).
3501
3502         // For credit packets, we'll update the credit.  Credit for each command number starts at
3503         // byte 12, or m_pbyPacketBuff[11].  Credit is a 2-byte signed value, so we have to multiply
3504         // the loop counter by 2 to get the right array index.  A byPacketType of 32 indicates
3505         // absolute credit, while a byPacketType value of 33 indicates incremental credit.
3506
3507         // For a command executed packet, we'll switch again and do the appropriate thing based upon
3508         // the command number for which the printer generated the response packet
3509         switch(byPacketType)
3510         {
3511             case ABSOLUTE_CREDIT:
3512                 if(bInitialize)
3513                 {
3514                     // Get number of commands to allocate memory for CreditCount buffer.
3515                     // Byte 11(byReadBuff[10])
3516                     byNumberOfCommands = m_pbyPacketBuff[NUMBER_OF_COMMANDS_BYTE];
3517
3518                     if(piCreditCount)
3519                     {
3520                         m_pSys->FreeMem((BYTE*)piCreditCount);
3521                     }
3522                     piCreditCount =
3523                         (short int *)(m_pSys->AllocMem(sizeof(short int) * byNumberOfCommands));
3524                     if(!piCreditCount)
3525                     {
3526                         return FALSE;
3527                     }
3528                     memset(piCreditCount, 0, (sizeof(short int) * byNumberOfCommands));
3529                 }
3530
3531                 for(by = 0; by < byNumberOfCommands; by++)
3532                 {
3533                     piCreditCount[by] = (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + dwBytesProcessed] << 8) |
3534                                         (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + 1 + dwBytesProcessed]);
3535                 }
3536
3537                 bUpdatedState = TRUE;
3538
3539                 break;
3540
3541             case INCREMENTAL_CREDIT:
3542                 if(bInitialize)
3543                 {
3544                     // If we're initializing we must wait for an absolute credit packet
3545                     break;
3546                 }
3547
3548                 for(by = 0; by < byNumberOfCommands; by++)
3549                 {
3550                     piCreditCount[by] += (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + dwBytesProcessed] << 8) |
3551                                          (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + 1 + dwBytesProcessed]);
3552                 }
3553
3554                 bUpdatedState = TRUE;
3555
3556                 break;
3557
3558 /*          case RESPONSE_COMMAND_EXECUTED:
3559                 if(bInitialize)
3560                 {
3561                     // If we're initializing we must wait for an absolute credit packet
3562                     return FALSE;
3563                 }
3564
3565                 // We should only get command number 5, which is the Query command
3566                 switch(byCommandNumber)
3567                 {
3568                     case COMMAND_QUERY:
3569                         // Copy status into LDLEncap's status buffer
3570                         memcpy(byStatusBuff, (m_pbyPacketBuff + dwBytesProcessed),
3571                               (wCommandLength + wDataLength));
3572                         bNewStatus = TRUE;
3573
3574                         break;
3575
3576                     default:
3577                         break;
3578                 } // switch(byCommandNumber)
3579
3580                 break;*/
3581
3582             case RESPONSE_AUTO:
3583                 if(bInitialize)
3584                 {
3585                     // If we're initializing we must wait for an absolute credit packet
3586                     break;
3587                 }
3588
3589                 // We should only get reference number 1, which is what I set up for the
3590                 // EOCStatusQuery command
3591                 switch(wReferenceNumber)
3592                 {
3593                     case AUTO_RESPONSE_STATUS:
3594
3595                         // Copy status into LDLEncap's status buffer
3596                         memcpy(byStatusBuff, (m_pbyPacketBuff + dwBytesProcessed),
3597                               (wCommandLength + wDataLength));
3598                         bNewStatus = TRUE;
3599                         bUpdatedState = TRUE;
3600
3601                         break;
3602
3603                     default:
3604
3605                         break;
3606                 } // switch(wReferenceNumber)
3607
3608                 break;
3609
3610             default:
3611                 if(bInitialize)
3612                 {
3613                     // If we're initializing we must wait for an absolute credit packet
3614                     break;
3615                 }
3616
3617                 break;
3618
3619         } // switch(byPacketType)
3620
3621         dwBytesProcessed += (DWORD)(wCommandLength + wDataLength);
3622     } // while(dwBytesProcessed < dwBytesRead)
3623
3624     return bUpdatedState;
3625 }
3626
3627 #ifdef  APDK_LDL_COMPRESS
3628
3629 /*
3630  *  Compression Related
3631  *  Mark Lund
3632  */
3633
3634
3635 ///////////////////////////////////////////////////////////////////////
3636 // Flush_Image
3637 ///////////////////////////////////////////////////////////////////////
3638
3639 UInt16 LDLEncap::FlushImage ()
3640 {
3641     UInt16    command;
3642     UInt16    wsize;
3643     UInt16    bsize;
3644     UInt16    *from_ptr;
3645     int       index;
3646
3647     wsize = m_ldlCompressData->image_cnt;
3648     bsize = 0;
3649
3650     if (wsize)
3651     {
3652         from_ptr = m_ldlCompressData->image_ptr;
3653
3654         command = FILL_IMAGE_CMD | (wsize-1);
3655
3656         index = 0;
3657         WRITE16(command);
3658         if (m_bLittleEndian)
3659         {
3660             *m_ldlCompressData->out_ptr++ = (((UInt16) m_szCmdBuf[1]) << 8) | m_szCmdBuf[0];
3661         }
3662         else
3663         {
3664             *m_ldlCompressData->out_ptr++ = command;
3665         }
3666 /*
3667         memcpy (m_ldlCompressData->out_ptr, from_ptr, sizeof (UInt16) * wsize);
3668         m_ldlCompressData->out_ptr += wsize;
3669 */
3670         for (UInt16 i = 0; i < wsize; i++)
3671         {
3672             *m_ldlCompressData->out_ptr++ = *from_ptr++;
3673         }
3674         bsize = ((m_ldlCompressData->image_cnt+1) * 2);
3675         m_ldlCompressData->out_cnt += bsize;
3676
3677         m_ldlCompressData->image_cnt = 0;
3678     }
3679
3680     return bsize;
3681 }
3682
3683 ///////////////////////////////////////////////////////////////////////
3684 // Flush_Copy
3685 ///////////////////////////////////////////////////////////////////////
3686 UInt16 LDLEncap::FlushCopy (UInt16 value)
3687 {
3688     UInt16    command;
3689     UInt16    size;
3690
3691     int       index;
3692
3693     size = m_ldlCompressData->copy_cnt;
3694
3695     if (size)
3696     {
3697         UInt16  *uP = m_ldlCompressData->out_ptr++;
3698         size = 2;
3699         if (value == 0)
3700         {
3701             command = FILL_0000_CMD | (m_ldlCompressData->copy_cnt-1);
3702         }
3703         else if (value == 0xFFFF)
3704         {
3705             command = FILL_FFFF_CMD | (m_ldlCompressData->copy_cnt-1);
3706         }
3707         else
3708         {
3709             command = FILL_NEXT_CMD | (m_ldlCompressData->copy_cnt-1);
3710 //            index = 0;
3711 //            WRITE16 (value);
3712             *m_ldlCompressData->out_ptr++ = value;
3713 //            *m_ldlCompressData->out_ptr++ = (((UInt16) m_szCmdBuf[1]) << 8) | m_szCmdBuf[0];
3714             size = 4;
3715         }
3716
3717         index = 0;
3718         WRITE16(command);
3719         if (m_bLittleEndian)
3720         {
3721             *uP = (((UInt16) m_szCmdBuf[1]) << 8) | m_szCmdBuf[0];
3722         }
3723         else
3724         {
3725             *uP = command;
3726         }
3727
3728         m_ldlCompressData->out_cnt += size;
3729         m_ldlCompressData->copy_cnt = 0;
3730     }
3731     return size;
3732 }
3733
3734 ///////////////////////////////////////////////////////////////////////
3735 // Compress_Data
3736 ///////////////////////////////////////////////////////////////////////
3737 void LDLEncap::CompressData (Int16 compressionmode)
3738 {
3739     Int16   i;
3740     UInt16  *in_ptr;
3741     UInt16  in;
3742     UInt16  last=0;
3743     UInt16  copy_item;
3744     UInt16  data_length;
3745
3746     LDLCOMPMODE mode = IN_NOT;
3747
3748
3749     m_ldlCompressData->out_cnt = 0;
3750     m_ldlCompressData->image_cnt = 0;
3751     m_ldlCompressData->copy_cnt = 0;
3752
3753     m_ldlCompressData->out_ptr = &m_ldlCompressData->out_array[8];
3754     data_length = m_ldlCompressData->data_length;
3755
3756     if ((data_length & 1) != 0)
3757     {
3758     //    ErrorTrap((char *)"Data length is odd.");
3759     }
3760
3761     copy_item = 0;
3762     in_ptr = &m_ldlCompressData->raw_data[0];
3763
3764     for (i=0; i<data_length; i+=2)
3765     {
3766         in = *in_ptr;
3767
3768         switch(mode)
3769         {
3770             case IN_NOT:
3771             {
3772                 /* default the first entry to 'image' */
3773                 last = in;
3774                 m_ldlCompressData->image_ptr = in_ptr;
3775                 m_ldlCompressData->image_cnt = 1;
3776                 mode = IN_FIRST;
3777                 break;
3778             }
3779
3780             case IN_FIRST:
3781             {
3782 #if ALLOW_FILL_NEXT_CMD
3783                 if (last == in)
3784 #else
3785                 if ((last == in) && ((in==0xFFFF) || (in == 0)) )
3786 #endif
3787                 {
3788                     mode = IN_COPY;
3789                     m_ldlCompressData->copy_cnt = 2;
3790                     m_ldlCompressData->image_cnt = 0;
3791                     copy_item = in;
3792                 }
3793                 else
3794                 {
3795                     mode = IN_IMAGE;
3796                     m_ldlCompressData->image_cnt++;
3797                     last = in;
3798                 }
3799                 break;
3800             }
3801
3802             case IN_COPY:
3803             {
3804                 if (last == in)
3805                 {
3806                     m_ldlCompressData->copy_cnt++;
3807                 }
3808                 else
3809                 {
3810                     /* revisit - could allow 2 words of copy if the data is
3811                     0000 or FFFF */
3812
3813                     /* convert a copy cnt of 2 to an image */
3814                     UInt16 copy_count = m_ldlCompressData->copy_cnt;
3815
3816                     if (copy_count <= m_ldlCompressData->run_length)
3817                     {
3818                         if (m_ldlCompressData->image_cnt == 0)
3819                         {
3820                             /* point the pointer to the first element */
3821                             m_ldlCompressData->image_ptr = in_ptr - copy_count;
3822                         }
3823                         m_ldlCompressData->image_cnt += (1+copy_count);
3824                      m_ldlCompressData->copy_cnt = 0;
3825                     }
3826                     else
3827                     {
3828                         /* have enough to be a legal copy */
3829
3830                         (void) FlushImage ();
3831
3832                         (void) FlushCopy (copy_item);
3833
3834                         m_ldlCompressData->image_ptr = in_ptr;
3835                         m_ldlCompressData->image_cnt = 1;
3836                     }
3837                     mode = IN_IMAGE;
3838                     last = in;
3839                 }
3840                 break;
3841             }
3842
3843             case IN_IMAGE:
3844             {
3845 #if ALLOW_FILL_NEXT_CMD
3846                 if (last == in)
3847 #else
3848                 if ((last == in) && ((in==0xFFFF) || (in == 0)) )
3849 #endif
3850                 {
3851                     m_ldlCompressData->image_cnt--;
3852
3853                     mode = IN_COPY;
3854                     copy_item = in;
3855                     m_ldlCompressData->copy_cnt = 2;
3856                 }
3857                 else /* different */
3858                 {
3859                     last = in;
3860                     m_ldlCompressData->image_cnt++;
3861                 }
3862                 break;
3863             }
3864
3865             default:
3866             {
3867                 break;
3868             }
3869         }
3870         in_ptr++;
3871     } /* next data - end of processing */
3872
3873     /* flush out the remainder */
3874
3875     switch(mode)
3876     {
3877         case IN_COPY:
3878         {
3879             /* have enough to be a legal copy */
3880             (void) FlushImage ();
3881
3882             (void) FlushCopy (copy_item);
3883             break;
3884         }
3885         case IN_IMAGE:
3886         case IN_FIRST:
3887         {
3888             (void) FlushImage ();
3889             break;
3890         }
3891         default:
3892             break;
3893     }
3894
3895     if (m_ldlCompressData->out_cnt > 2048+16)
3896     {
3897     //    ErrorTrap("out cnt too big");
3898     //    exit (-7);
3899     }
3900 }
3901
3902 /////////////////////////////////////////////////////////////////////////////////
3903 //GetFrameInfo 
3904 /////////////////////////////////////////////////////////////////////////////////
3905 BOOL LDLEncap::GetFrameInfo (BYTE **outdata, UInt16 *data_size)
3906 {
3907     *outdata = (unsigned char *) &m_ldlCompressData->out_array[0];
3908     *data_size = m_ldlCompressData->out_cnt;
3909     return(TRUE);
3910 }
3911
3912 /////////////////////////////////////////////////////////////////////////////////
3913 //Init: to init/reinit the data structure. 
3914 /////////////////////////////////////////////////////////////////////////////////
3915 BOOL comp_ptrs_t::Init (UInt16 *data, UInt16 datasize)
3916 {
3917         image_ptr   = data;
3918         raw_data    = data;
3919         data_length = datasize;
3920
3921         run_length = MAX_RUNLENGTH;
3922         display = 0;
3923
3924         return(TRUE);
3925 }
3926 #endif  // APDK_LDL_COMPRESS
3927
3928 APDK_END_NAMESPACE
3929
3930 #endif  // APDK_DJ3320