1 /*****************************************************************************\
2 dj3320.cpp : Implimentation for the DJ3320 class
4 Copyright (c) 2001 - 2006, Hewlett-Packard Co.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. Neither the name of Hewlett-Packard nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \***************************************************************************/
36 #include "resources.h"
37 #include "printerproxy.h"
40 extern BYTE* GetHT3x3_4();
41 extern BYTE* GetHT6x6_4_970();
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 ];
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];
61 extern void AsciiHexToBinary(BYTE* dest, char* src, int count);
65 //#define DBG2(str, i) {}
66 //#define DBG3(str, i, j) {}
68 DJ3320::DJ3320 (SystemServices* pSS, BOOL proto)
69 : Printer(pSS,NUM_DJ6XX_FONTS,proto), m_dsCurrentStatus(DISPLAY_PRINTING)
75 m_iColorPenResolution = 300;
\r
76 m_iBlackPenResolution = 1200;
\r
77 m_iNumBlackNozzles = 400;
81 bCheckForCancelButton = TRUE;
82 constructor_error = VerifyPenInfo ();
84 // pSS->GetVertAlignFromDevice();
87 ePen = BOTH_PENS; // matches default mode
88 CMYMap = ulMapDJ3320_CMY_3x3x1;
93 pSS->FreeMem (pSendBuffer);
95 pSendBuffer = pSS->AllocMem (iBuffSize);
96 CNEWCHECK (pSendBuffer);
99 void DJ3320::InitPrintModes ()
101 if (ePen == BLACK_PEN || ePen == MDL_PEN)
103 pMode[GRAYMODE_INDEX] = new DJ3320KDraftMode ();
104 pMode[DEFAULTMODE_INDEX] = new DJ3320GrayMode (ePen);
107 else if (ePen == BOTH_PENS)
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);
116 else if (ePen == MDL_BOTH)
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 ();
127 pMode[DEFAULTMODE_INDEX] = new DJ3320NormalMode (ePen);
128 pMode[SPECIALMODE_INDEX] = new DJ3320PhotoMode ();
129 pMode[GRAYMODE_INDEX] = new DJ3320DraftMode (ePen);
134 DRIVER_ERROR DJ3320::SetPens (PEN_TYPE eNewPen)
140 ASSERT (eNewPen <= MAX_PEN_TYPE);
141 if (eNewPen > MAX_PEN_TYPE)
143 return UNSUPPORTED_PEN;
146 for (int i = 0; i < (int) ModeCount; i++)
163 if (ePen == COLOR_PEN && pMode[GRAYMODE_INDEX])
165 delete pMode[GRAYMODE_INDEX];
166 pMode[GRAYMODE_INDEX] = NULL;
171 pSS->FreeMem ((BYTE *) pSendBuffer);
175 DJ3320GrayMode::DJ3320GrayMode (PEN_TYPE ePen) : PrintMode (ulMapDJ3320_K_6x6x1)
177 if (ePen == MDL_BOTH)
179 cmap.ulMap2 = ulMapDJ3600_ClMlxx_6x6x1;
185 CompatiblePens[1] = BLACK_PEN;
186 CompatiblePens[2] = MDL_BOTH;
187 CompatiblePens[3] = MDL_PEN;
189 ResolutionX[0] = 600;
190 ResolutionY[0] = 600;
196 bFontCapable = FALSE;
197 Config.bCompress = FALSE;
200 DJ3320KDraftMode::DJ3320KDraftMode () : GrayMode (ulMapDJ3320_K_3x3x1)
202 bFontCapable = FALSE;
203 Config.bCompress = FALSE;
204 theQuality = qualityDraft;
205 pmQuality = QUALITY_DRAFT;
206 CompatiblePens[2] = MDL_BOTH;
207 CompatiblePens[3] = MDL_PEN;
210 DJ3320DraftMode::DJ3320DraftMode (PEN_TYPE ePen)
211 : PrintMode (ulMapDJ3320_KCMY_3x3x1)
214 if (ePen == COLOR_PEN)
216 CompatiblePens[1] = ePen;
217 cmap.ulMap1 = ulMapDJ3320_CMY_3x3x1;
221 for (int i = 0; i < 4; i++)
225 ResolutionX[i] = 300;
226 ResolutionY[i] = 300;
231 bFontCapable = FALSE;
232 pmQuality = QUALITY_DRAFT;
233 Config.bCompress = FALSE;
235 // strcpy(ModeName, "Draft");
238 DJ3320NormalMode::DJ3320NormalMode (PEN_TYPE ePen)
239 : PrintMode (ulMapDJ3320_KCMY_6x6x1)
242 if (ePen == COLOR_PEN)
244 CompatiblePens[1] = ePen;
245 cmap.ulMap1 = ulMapDJ3320_CMY_6x6x1;
249 for (int i = 0; i < 4; i++)
253 ResolutionX[i] = 600;
254 ResolutionY[i] = 600;
261 bFontCapable = FALSE;
262 Config.bCompress = FALSE;
264 // strcpy(ModeName, "Normal");
267 DJ3320PhotoMode::DJ3320PhotoMode ()
268 : PrintMode (ulMapDJ970_Gossimer_Normal_KCMY)
271 for (int i = 0; i < 4; i++)
275 ResolutionX[i] = 600;
276 ResolutionY[i] = 600;
279 CompatiblePens[1] = COLOR_PEN;
285 ColorFEDTable = GetHT6x6_4_970 ();
287 bFontCapable = FALSE;
289 pmQuality = QUALITY_BEST;
290 pmMediaType = MEDIA_PHOTO;
292 medium = mediaGlossy;
293 theQuality = qualityPresentation;
295 Config.bCompress = FALSE;
300 // Plain Normal Print Mode for Photo and Color Pen
302 DJ3600MDLNormalMode::DJ3600MDLNormalMode()
303 : PrintMode( ulMapDJ3600_KCMY_6x6x1, ulMapDJ3600_ClMlxx_6x6x1 )
306 CompatiblePens[0] = MDL_BOTH;
308 for (int i = 0; i < 6; i++)
312 ResolutionX[i] = 600;
313 ResolutionY[i] = 600;
320 bFontCapable = FALSE;
321 Config.bCompress = FALSE;
325 // Photo Best Print Mode for Photo and Color Pen
327 DJ3600MDLPhotoMode::DJ3600MDLPhotoMode()
328 : PrintMode( ulMapDJ3600_KCMY_6x6x2, ulMapDJ3600_ClMlxx_6x6x2 )
331 CompatiblePens[0] = MDL_BOTH;
333 for (int i = 0; i < 6; i++)
337 ResolutionX[i] = 600;
338 ResolutionY[i] = 600;
346 ColorFEDTable = (BYTE*) HT600x6004level3600_open;
348 bFontCapable = FALSE;
350 pmQuality = QUALITY_BEST;
351 pmMediaType = MEDIA_PHOTO;
353 medium = mediaGlossy;
354 theQuality = qualityPresentation;
355 Config.bCompress = FALSE;
359 // Draft Mode for Photo and Color Pen
361 DJ3600MDLDraftMode::DJ3600MDLDraftMode()
362 : PrintMode( ulMapDJ3600_KCMY_3x3x1, ulMapDJ3600_ClMlxx_3x3x1 )
365 CompatiblePens[0] = MDL_BOTH;
367 for (int i = 0; i < 6; i++)
371 ResolutionX[i] = 300;
372 ResolutionY[i] = 300;
379 bFontCapable = FALSE;
380 pmQuality = QUALITY_DRAFT;
381 Config.bCompress = FALSE;
384 DRIVER_ERROR DJ3320::Encapsulate (const RASTERDATA *pRasterData, BOOL bLastPlane)
386 return pLDLEncap->Encapsulate (pRasterData->rasterdata[COLORTYPE_COLOR], pRasterData->rastersize[COLORTYPE_COLOR], bLastPlane);
389 Header* DJ3320::SelectHeader(PrintContext* pc)
391 pLDLEncap = new LDLEncap (this, pSS, pc);
393 pLDLEncap->AllocateSwathBuffer ((pc->OutputPixelsPerRow ()) / 8 + 2);
394 if (pLDLEncap->constructor_error != NO_ERROR)
397 return new Header3320 (this,pc);
401 * Author: Don Castrapel
404 DISPLAY_STATUS DJ3320::ParseError (BYTE byStatusReg)
406 DRIVER_ERROR err = NO_ERROR;
407 BYTE byDevIDBuffer[DevIDBuffSize];
409 BYTE byStatus1, byStatus2;
411 memset(byDevIDBuffer, 0, sizeof(byDevIDBuffer));
412 byStatus1 = byStatus2 = 0;
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);
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;
429 if(pLDLEncap->bNewStatus)
431 pLDLEncap->bNewStatus = FALSE;
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)
436 m_dsCurrentStatus = DISPLAY_COMM_PROBLEM;
437 return DISPLAY_COMM_PROBLEM;
440 // Point to first byte of Feature State. Skip 3 bytes for "$S:", 2 for version
444 if (byStatus1 == '9')
446 iTotal_SLOW_POLL_Count = 0;
447 m_dsCurrentStatus = DISPLAY_TOP_COVER_OPEN;
448 return DISPLAY_TOP_COVER_OPEN;
451 // Point to Printer State. Skip 14-byte Feature State
453 byStatus1 = *pcStr++;
454 byStatus2 = *pcStr++;
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'))
461 iTotal_SLOW_POLL_Count = 0;
462 m_dsCurrentStatus = DISPLAY_PRINTING_CANCELED;
463 return DISPLAY_PRINTING_CANCELED;
465 if ((byStatus1 == '0') && (byStatus2 == '9'))
468 iTotal_SLOW_POLL_Count = 0;
469 m_dsCurrentStatus = DISPLAY_OUT_OF_PAPER_NEED_CONTINUE;
470 return DISPLAY_OUT_OF_PAPER_NEED_CONTINUE;
472 if ((byStatus1 == '0') && (byStatus2 == 'E'))
475 iTotal_SLOW_POLL_Count = 0;
476 m_dsCurrentStatus = DISPLAY_ERROR_TRAP;
477 return DISPLAY_ERROR_TRAP;
479 if ((byStatus1 == '0') && (byStatus2 == 'F'))
481 // 0F = Carriage stall
482 iTotal_SLOW_POLL_Count = 0;
483 m_dsCurrentStatus = DISPLAY_ERROR_TRAP;
484 return DISPLAY_ERROR_TRAP;
486 if ((byStatus1 == '1') && (byStatus2 == '0'))
489 iTotal_SLOW_POLL_Count = 0;
490 m_dsCurrentStatus = DISPLAY_ERROR_TRAP;
491 return DISPLAY_ERROR_TRAP;
494 // No problem detectable from status string. Set default condition
495 m_dsCurrentStatus = DISPLAY_PRINTING;
498 // VerifyPenInfo will handle prompting the user if this is a problem
499 err = VerifyPenInfo();
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;
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++;
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)
519 return m_dsCurrentStatus;
523 * Author: Don Castrapel
526 DRIVER_ERROR DJ3320::Send (const BYTE* pWriteBuff, DWORD dwWriteCount)
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;
542 BOOL bOriginalRequest = TRUE;
544 // DJ3400 doesn't use a staus reg, but we need one for the call to ParseError
545 BYTE byStatusReg = 0;
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;
555 // Retry, query, and cancel variables
556 BOOL bPrinterCancelButton = FALSE;
557 BOOL bCanceling = FALSE;
558 BOOL bCanceled = FALSE;
560 ////////////////////////////////////////////////////////////////
562 // test imaging speed independent of printer I/O, will not
563 // send any data to the device
566 ////////////////////////////////////////////////////////////////
570 return pSS->ToDevice (pWriteBuff, &dwSendSize);
573 if (ErrorTerminationState)
575 // Don't try any more I/O if we previously terminated in an error state
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.
583 if (dwWriteCount == 0)
584 // Don't bother processing an empty Send call
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];
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
595 byCommandNumber = pWriteBuff[COMMAND_NUMBER_BYTE];
596 byCommandNumberOriginal = pWriteBuff[COMMAND_NUMBER_BYTE];
601 // Just flush whatever is in the buffer
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)
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.
615 // Check to see if we have credit for this command
616 if (pLDLEncap->piCreditCount[byCommandNumber] > 0)
618 pLDLEncap->piCreditCount[byCommandNumber]--;
619 bCreditForCommand = TRUE;
620 byCreditWaitCount = 0;
626 bUpdateState = pLDLEncap->UpdateState (FALSE);
630 // Rechecking here will save us a trip through the do loop
631 if (pLDLEncap->piCreditCount[byCommandNumber] > 0)
633 pLDLEncap->piCreditCount[byCommandNumber]--;
634 bCreditForCommand = TRUE;
635 byCreditWaitCount = 0;
642 // Special packet types get a free pass
643 bCreditForCommand = TRUE;
645 } // if(!bCreditForCommand)
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)
652 if (bCreditForCommand)
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))
658 pBuffer = pWriteBuff + (dwWriteCount - BytesToWrite);
659 dwSendSize = BytesToWrite;
660 BytesToWrite = 0; // This is checked for at the end of the outer loop
662 else // We will buffer this data
664 // If it'll fit then just copy everything to the buffer
665 if (BytesToWrite <= (DWORD) iBuffSize - iCurrBuffSize)
667 memcpy ((void*) (pSendBuffer + iCurrBuffSize),
668 (void*) (pWriteBuff + (dwWriteCount - BytesToWrite)),
670 iCurrBuffSize += BytesToWrite;
673 else // Copy what we can into the buffer, we'll get the rest later
675 memcpy ((void*) (pSendBuffer + iCurrBuffSize),
676 (void*) (pWriteBuff + (dwWriteCount - BytesToWrite)),
677 iBuffSize - iCurrBuffSize);
678 BytesToWrite -= (iBuffSize - iCurrBuffSize);
679 iCurrBuffSize = iBuffSize;
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)
689 } // if (bCreditForCommand)
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) )
696 // We're not ready to send yet. Break out of do loop
699 else // Send this buffered data
705 pBuffer = pSendBuffer;
706 dwSendSize = iCurrBuffSize;
709 // Initialize our 'residual' to the full send size
710 dwResidual = dwSendSize;
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
716 if(bCheckForCancelButton && (ulBytesSentSinceCancelCheck >= CANCEL_BUTTON_CHECK_THRESHOLD))
718 ulBytesSentSinceCancelCheck = 0;
720 if(ParseError(byStatusReg) == DISPLAY_PRINTING_CANCELED)
721 bPrinterCancelButton = TRUE;
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.
732 // While still data to send in this request
733 while (dwResidual > 0)
735 // WritePort overwrites request count, need to save
736 dwPrevResidual = dwResidual;
738 pWritePos = (const BYTE *) &(pBuffer[dwSendSize - dwResidual]);
739 err = pSS->ToDevice (pWritePos, &dwResidual);
743 ErrorTerminationState = TRUE;
747 // No more data to send this time
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
753 err = pSS->FlushIO ();
756 ErrorTerminationState = TRUE;
759 // We successfully sent the entire non-original request, so reset to original
761 if(!bOriginalRequest && !bCanceled)
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
781 iTotal_SLOW_POLL_Count = 0;
784 break; // Out of while loop
788 if (dwPrevResidual == dwResidual)
790 // The I/O didn't take any data, increment count
795 // The I/O took some data, although not the full request
801 // If I/O hasn't finished after our timeout limit, we have to bail.
802 if (byIOWaitCount >= IO_WAIT)
804 ErrorTerminationState = TRUE;
805 pSS->DisplayPrinterStatus (DISPLAY_COMM_PROBLEM);
809 // Check for user cancel each time through loop
810 if (pSS->BusyWait ((DWORD)0) == JOB_CANCELED)
812 pSS->DisplayPrinterStatus (DISPLAY_PRINTING_CANCELED);
815 } // while (residual > 0)
819 } // if(bCreditForCommand || bFlush)
822 // If we can't get credit and we've exceeded our wait limit, check for an error
823 if (byCreditWaitCount >= CREDIT_WAIT)
825 if(!bOriginalRequest)
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;
832 // Flush our internal buffer so that we can send command such as query or continue
839 // See if we can find out what's wrong
840 eDisplayStatus = ParseError(byStatusReg);
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.
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)
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;
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
865 ErrorTerminationState = TRUE;
866 pSS->DisplayPrinterStatus (eDisplayStatus);
868 // Wait for user to cancel the job, otherwise they might miss the
870 while (pSS->BusyWait ((DWORD) 500) != JOB_CANCELED)
878 case DISPLAY_TOP_COVER_OPEN:
879 pSS->DisplayPrinterStatus(DISPLAY_TOP_COVER_OPEN);
883 // Wait for top cover to close or user to cancel
884 while(eDisplayStatus == DISPLAY_TOP_COVER_OPEN && !err)
886 err = pSS->BusyWait((DWORD)500);
887 if(err == JOB_CANCELED)
889 ErrorTerminationState = TRUE;
894 bUpdateState = pLDLEncap->UpdateState(FALSE);
897 eDisplayStatus = ParseError(byStatusReg);
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)
903 ErrorTerminationState = TRUE;
904 bPrinterCancelButton = TRUE;
908 } // while(eDisplayStatus == DISPLAY_TOP_COVER_OPEN && !err)
910 if(!err && !bPrinterCancelButton)
912 pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
914 // Give the printer some time to come back online
915 if(pSS->BusyWait((DWORD)1000) == JOB_CANCELED)
917 ErrorTerminationState = TRUE;
923 case DISPLAY_OUT_OF_PAPER_NEED_CONTINUE:
924 pSS->DisplayPrinterStatus (DISPLAY_OUT_OF_PAPER_NEED_CONTINUE);
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)
932 err = pSS->BusyWait((DWORD)500);
934 if (err == JOB_CANCELED)
936 ErrorTerminationState = TRUE;
938 else if(err == CONTINUE_FROM_BLOCK)
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;
952 bUpdateState = pLDLEncap->UpdateState(FALSE);
955 eDisplayStatus = ParseError(byStatusReg);
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)
961 ErrorTerminationState = TRUE;
962 bPrinterCancelButton = TRUE;
966 } // while(eDisplayStatus == DISPLAY_OUT_OF_PAPER_NEED_CONTINUE && !err)
968 if(!err && !bPrinterCancelButton)
970 pSS->DisplayPrinterStatus(DISPLAY_PRINTING);
976 pSS->DisplayPrinterStatus(DISPLAY_BUSY);
978 if (pSS->BusyWait ((DWORD) 5000) == JOB_CANCELED)
980 ErrorTerminationState = TRUE;
985 // Other cases need no special handling, display the error and try to continue
987 pSS->DisplayPrinterStatus (eDisplayStatus);
989 if (pSS->BusyWait ((DWORD) 500) == JOB_CANCELED)
991 ErrorTerminationState = TRUE;
995 } // switch(eDisplayStatus)
996 } // else(iCurrBuffSize)
997 } // if(byCreditWaitCount >= CREDIT_WAIT)
998 } // else(bCreditForCommand || bFlush)
1000 if (pSS->BusyWait ((DWORD)0) == JOB_CANCELED || bPrinterCancelButton)
1002 pSS->DisplayPrinterStatus(DISPLAY_PRINTING_CANCELED);
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.
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.
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.
1017 // After we check for these conditions we can send the Prepare to Cancel and Cancel
1019 if( (iCurrBuffSize || (BytesToWrite && bCreditForCommand && !ErrorTerminationState) ) &&
1020 !(bCanceling || bCanceled) )
1024 else if(!bCanceling)
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;
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)
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;
1052 } while (BytesToWrite > 0);
1056 // Ensure that display still says we're cancelling
1057 pSS->DisplayPrinterStatus(DISPLAY_PRINTING_CANCELED);
1058 ErrorTerminationState = TRUE;
1059 return JOB_CANCELED;
1063 // Ensure any error message has been cleared
1064 pSS->DisplayPrinterStatus (DISPLAY_PRINTING);
1065 if (bCheckForCancelButton)
1067 ulBytesSentSinceCancelCheck += dwWriteCount;
1073 DRIVER_ERROR DJ3320::ParsePenInfo (PEN_TYPE& ePen, BOOL QueryPrinter)
1079 DRIVER_ERROR err = SetPenInfo (str, QueryPrinter);
1082 // the first byte indicates how many pens are supported
1083 if ((str[0] >= '0') && (str[0] <= '9'))
1085 num_pens = str[0] - '0';
1087 else if ((str[0] >= 'A') && (str[0] <= 'F'))
1089 num_pens = 10 + (str[0] - 'A');
1093 return BAD_DEVICE_ID;
1096 if ((int) strlen (str) < (num_pens * 8))
1098 return BAD_DEVICE_ID;
1102 BYTE penInfoBits[4];
1108 1 if these fields describe a print head
1112 1 if these fields describe an ink supply
1115 Bits 29 .. 24 (6 bits) describes the pen/supply type:
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
1133 for (int i = 0; i < num_pens; i++, p += 8)
1135 AsciiHexToBinary (penInfoBits, p, 8);
1136 if ((penInfoBits[1] & 0xf8) == 0xf8)
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;
1142 if ((penInfoBits[0] & 0x80) != 0x80) // if Bit 31 is 0, this is not a pen
1146 BYTE penColor = penInfoBits[0] & 0x3F;
1158 if (ePen == BLACK_PEN)
1162 else if (ePen == MDL_PEN)
1173 if (ePen == BLACK_PEN)
1175 ePen = MDL_AND_BLACK_PENS;
1177 else if (ePen == COLOR_PEN)
1181 else if (ePen == BOTH_PENS)
1183 ePen = MDL_BLACK_AND_COLOR_PENS;
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)
1213 DRIVER_ERROR DJ3320::VerifyPenInfo()
1216 DRIVER_ERROR err = NO_ERROR;
1218 if(IOMode.bDevID == FALSE)
1223 err = ParsePenInfo(ePen);
1226 while (ePen == NO_PEN)
1228 err = ParsePenInfo (ePen);
1232 pSS->DisplayPrinterStatus (DISPLAY_NO_PENS);
1233 if (pSS->BusyWait (500) == JOB_CANCELED)
1234 return JOB_CANCELED;
1239 pSS->DisplayPrinterStatus (DISPLAY_PRINTING);
1244 DRIVER_ERROR DJ3320::CheckInkLevel()
1249 BYTE bDevIDBuff[DevIDBuffSize];
1256 err = pSS->GetDeviceID(bDevIDBuff, DevIDBuffSize, TRUE);
1262 if ( (pStr=(char *)strstr((const char*)bDevIDBuff+2,";S:")) == NULL )
1269 if (*pStr > '0' && *pStr < '9')
1271 numPens = *pStr - '0';
1273 else if (*pStr > 'A' && *pStr < 'F')
1275 numPens = *pStr - 'A';
1277 else if (*pStr > 'a' && *pStr < 'f')
1279 numPens = *pStr - 'a';
1284 BYTE penInfoBits[4];
1289 for (int i = 0; i < numPens; i++, pStr += 8)
1291 AsciiHexToBinary (penInfoBits, pStr, 8);
1293 if ((penInfoBits[0] & 0x80) != 0x80) // if Bit 31 is 0, this is not a pen
1297 int penColor = penInfoBits[0] & 0x3F;
1301 blackink = penInfoBits[1] & 0x7;
1304 colorink = penInfoBits[1] & 0x7;
1307 photoink = penInfoBits[1] & 0x7;
1310 greyink = penInfoBits[1] & 0x7;
1318 colorink = penInfoBits[1] & 0x7; // REVISIT: these are C, M, Y respectively
1324 if (blackink < 2 && colorink < 2 && photoink < 2 && greyink < 2)
1328 else if (blackink > 1 && colorink > 1 && photoink > 1)
1330 return WARN_LOW_INK_COLOR_BLACK_PHOTO;
1332 else if (greyink > 1 && colorink > 1 && photoink > 1)
1334 return WARN_LOW_INK_COLOR_GREY_PHOTO;
1336 else if (blackink > 1 && colorink > 1)
1338 return WARN_LOW_INK_BOTH_PENS;
1340 else if (blackink > 1 && photoink > 1)
1342 return WARN_LOW_INK_BLACK_PHOTO;
1344 else if (greyink > 1 && colorink > 1)
1346 return WARN_LOW_INK_COLOR_GREY;
1348 else if (greyink > 1 && photoink > 1)
1350 return WARN_LOW_INK_GREY_PHOTO;
1352 else if (colorink > 1 && photoink > 1)
1354 return WARN_LOW_INK_COLOR_PHOTO;
1356 else if (blackink > 1)
1358 return WARN_LOW_INK_BLACK;
1360 else if (colorink > 1)
1362 return WARN_LOW_INK_COLOR;
1364 else if (photoink > 1)
1366 return WARN_LOW_INK_PHOTO;
1368 else if (greyink > 1)
1370 return WARN_LOW_INK_GREY;
1372 else if (colorink > 1)
1374 return WARN_LOW_INK_COLOR;
1383 DRIVER_ERROR DJ3320::SkipRasters (int nBlankRasters)
1385 return (pLDLEncap->SetVerticalSkip (nBlankRasters));
1388 DRIVER_ERROR DJ3320::CleanPen()
1390 return pLDLEncap->CleanPen ();
1393 DRIVER_ERROR DJ3320::Flush (int FlushSize)
1395 pLDLEncap->Flush ();
1399 Header3320::Header3320 (Printer* p,PrintContext* pc)
1405 DRIVER_ERROR Header3320::FormFeed ()
1407 return (((DJ3320 *) thePrinter)->pLDLEncap->EndPage ());
1410 DRIVER_ERROR Header3320::EndJob()
1412 ((DJ3320 *) thePrinter)->pLDLEncap->EndJob ();
1416 DRIVER_ERROR Header3320::Send ()
1419 DJ3320 *pXBow = (DJ3320 *) thePrinter;
1421 return (pXBow->pLDLEncap->StartJob ());
1425 DRIVER_ERROR Header3320::SendCAPy (unsigned int iAbsY)
1430 LDLEncap::LDLEncap (DJ3320 *pPrinter, SystemServices *pSys, PrintContext *pc)
1433 constructor_error = NO_ERROR;
1434 piCreditCount = NULL;
1436 pPrinterXBow = pPrinter;
1437 m_iXResolution = pc->EffectiveResolutionX ();
1438 m_iYResolution = pc->EffectiveResolutionY ();
1440 m_cPrintDirection = PRNDRN_LEFTTORIGHT;
1443 m_iBlankRasters = 0;
1445 m_iVertPosn = (int) (m_pthisPC->PrintableStartY () * DEVUNITS_XBOW);
1447 m_iLeftMargin = (int) (m_pthisPC->PrintableStartX () * DEVUNITS_XBOW);
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,
1458 &fXOverSpray, &fYOverSpray,
1459 &fLeftOverSpray, &fTopOverSpray))
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.
1470 m_iVertPosn = (int) (-fTopOverSpray * DEVUNITS_XBOW);
1471 m_iLeftMargin = (int) (-fLeftOverSpray * DEVUNITS_XBOW);
1474 m_bStartPageNotSent = TRUE;
1481 m_cPrintQuality = (BYTE) QUALITY_NORMAL;
1482 m_cMediaType = (BYTE) MEDIA_PLAIN;
1489 DRIVER_ERROR err = m_pthisPC->GetPrintModeSettings (cqm, cmt, ccm, cdt);
1490 if (err == NO_ERROR)
1492 if (cqm == QUALITY_BEST && cmt == MEDIA_PHOTO)
1494 m_cPrintQuality = (BYTE) cqm;
1495 m_cMediaType = (BYTE) cmt;
1499 if (pPrinterXBow->ePen == BLACK_PEN || pPrinterXBow->ePen == MDL_PEN || cm == GREY_K)
1501 else if (pPrinterXBow->ePen == COLOR_PEN || cm == GREY_CMY)
1503 else if (pPrinterXBow->ePen == BOTH_PENS && m_iBitDepth == 2)
1505 else if (pPrinterXBow->ePen == MDL_BOTH)
1508 m_bBidirectionalPrintingOn = TRUE; //FALSE;
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
1516 m_szCmdBuf = new BYTE[mem_needed];
1517 CNEWCHECK (m_szCmdBuf);
1519 m_bLittleEndian = TRUE;
1528 m_bLittleEndian = FALSE;
1531 m_szCmdBuf[0] = FRAME_SYN;
1539 // Pacing and status handling data
1541 memset(byStatusBuff, 0, sizeof(byStatusBuff));
1543 m_pbyPacketBuff = NULL;
1544 m_pbyPacketBuff = pSys->AllocMem (MAX_PACKET_READ_SIZE);
1545 CNEWCHECK (m_pbyPacketBuff);
1547 m_dwPacketBuffSize = MAX_PACKET_READ_SIZE;
1549 // Setup Sync command
1550 pbySync = m_pSys->AllocMem(SYNCSIZE);
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);
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.
1565 BYTE cVertAlign = 0;
1566 if (pPrinterXBow->ePen == BOTH_PENS)
1568 if (pSys->GetVerticalAlignmentValue(&cVertAlign))
1570 m_cKtoCVertAlign = cVertAlign;
1574 m_cKtoCVertAlign = 12;
1577 else if (pPrinterXBow->ePen == MDL_BOTH)
1579 if (pSys->GetVerticalAlignmentValue(&cVertAlign))
1581 m_cPtoCVertAlign = cVertAlign;
1585 m_cPtoCVertAlign = 6;
1590 m_cKtoCVertAlign = 12;
1591 m_cPtoCVertAlign = 6;
1595 void LDLEncap::AllocateSwathBuffer (unsigned int RasterSize)
1597 int size = RasterSize;
1598 size = (size / 8 + 1) * 8;
1599 m_iImageWidth = size;
1601 constructor_error = NO_ERROR;
1602 m_ldlCompressData = NULL;
1604 #ifdef APDK_LDL_COMPRESS
1605 if (pPrinterXBow->m_iLdlVersion == 1)
1607 m_ldlCompressData = new comp_ptrs_t;
1611 if (m_iBitDepth == 2)
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);
1625 m_sSwathHeight = SWATH_HEIGHT;
1628 * This swath buffer cannot be greater than the number of nozzles - 400 for black
1629 * and 100 for color - we can use.
1632 int iAdjHeight = (pPrinterXBow->m_iNumBlackNozzles / 32) * 8;
1633 if (pPrinterXBow->ePen == BLACK_PEN)
1635 m_sSwathHeight = m_sSwathHeight * 4;
1636 if (m_sSwathHeight * 1200 / m_iYResolution > pPrinterXBow->m_iNumBlackNozzles)
1637 m_sSwathHeight = m_iYResolution / 3;
1639 else if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution > 300 && m_iNumColors > 1 && m_iBitDepth == 1) // Collie change
1641 m_sSwathHeight = (m_sSwathHeight / 4) * 4 * 2;
1642 if (m_sSwathHeight > 200)
1643 m_sSwathHeight = 200;
1646 else if (m_iBitDepth == 2)
1647 m_sSwathHeight = iAdjHeight * 4;
1649 if (m_cPrintQuality == QUALITY_NORMAL)
1650 m_sSwathHeight = iAdjHeight * 2;
1652 if (m_cPrintQuality == QUALITY_DRAFT && pPrinterXBow->ePen != BLACK_PEN)
1654 m_sSwathHeight *= iSwings;
1657 while (m_sSwathHeight > 16)
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)
1664 m_sSwathHeight = (m_sSwathHeight / 16) * 8;
1669 if (m_sSwathHeight < 16)
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);
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 *));
1684 for (i = 0; i < m_iNumColors; i++)
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++)
1691 memset (p, 0, size);
1692 m_SwathData[i][j] = p;
1697 if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
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);
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,
1712 &fXOverSpray, &fYOverSpray,
1713 &fLeftOverSpray, &fTopOverSpray))
1715 if (m_iVertPosn < -850) m_iVertPosn = -850;
1719 if (m_iVertPosn < -600) m_iVertPosn = -600;
1721 if (m_iBitDepth == 2)
1725 unsigned int LDLEncap::GetSwathWidth (int iStart, int iLast, int iWidth)
1729 for (i = iWidth - 1 /*sizeof (long)*/; i > -1; i--)
1731 for (j = iStart; j < iLast; j++)
1733 for (k = m_iRasterCount / m_iNumColors-1; k >= 0; k--)
1736 if (m_SwathData[j][k][i])
1747 void LDLEncap::Flush ()
1749 // if (m_iRasterCount)
1750 // Process (NULL, 0);
1753 DRIVER_ERROR LDLEncap::SetVerticalSkip (int nBlankRasters)
1755 DRIVER_ERROR err = NO_ERROR;
1757 if (m_iRasterCount == 0)
1759 m_iBlankRasters += nBlankRasters;
1763 int iCount = m_iNumColors * m_iBitDepth;
1764 if (m_iBitDepth == 2 && m_iNumColors != 6)
1767 while (nBlankRasters > 0)
1769 for (int i = 0; i < iCount; i++)
1771 err = Encapsulate (NULL, m_iImageWidth, 0);
1779 BOOL LDLEncap::IsBlankRaster (BYTE *raster, int width)
1790 DRIVER_ERROR LDLEncap::Encapsulate (const BYTE *input, DWORD size, BOOL bLastPlane)
1792 DRIVER_ERROR err = NO_ERROR;
1794 if (size > (DWORD) m_iImageWidth)
1795 size = m_iImageWidth;
1796 if (m_iBitDepth == 2)
1798 if (m_iNumColors != 6)
1800 if (m_cPlaneNumber == 0)
1807 if (m_iNumColors == 6)
1809 iPlaneNum = m_cPlaneNumber % 2;
1813 iPlaneNum = (m_cPlaneNumber + 1) % 2;
1815 int iRowNum = (m_iRasterCount / 6) * 2 + iPlaneNum;
1816 iRowNum = m_iNextRaster;
1817 if (m_iNumColors == 6)
1819 iCPlane = m_cPlaneNumber / 2;
1823 iCPlane = (m_cPlaneNumber - 1) / 2;
1828 memset (m_SwathData[iCPlane][iRowNum], 0, m_iImageWidth * 2);
1830 memcpy (m_SwathData[iCPlane][iRowNum], input, size);
1832 if (m_iNumColors == 6)
1834 m_cPlaneNumber = (m_cPlaneNumber + 1) % 12;
1838 m_cPlaneNumber = (m_cPlaneNumber + 1) % 8;
1843 // do the dotmapping here
1844 BYTE cbyte1, cbyte2;
1851 BYTE bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
1854 int iNextBitPos = m_iImageWidth;
1855 int iJIncrement = 1;
1856 if (pPrinterXBow->m_iLdlVersion == 2)
1862 memcpy (m_szCompressBuf, m_SwathData[iCPlane][m_iNextRaster], size);
1864 static BYTE rand_table[4][4] = {{0, 3, 1, 2},
1872 for (unsigned int i = 0; i < size; i++)
1874 cbyte2 = m_szCompressBuf[i];
1875 cbyte1 = (input == NULL) ? 0 : input[i];
1877 // 1200 dpi raster split into 2 600 dpi rasters
1884 for (int ibit = 0; ibit < 8; ibit++)
1886 c1 = (cbyte1 & bitmask[ibit]) ? 1 : 0;
1887 c2 = (cbyte2 & bitmask[ibit]) ? 1 : 0;
1890 rt2 = (i + ibit) % 4;
1891 rt2 = rand_table[rt1][rt2];
1897 r1b1 = r1b1 | (0xff & (cbyte1 & bitmask[ibit]));
1898 r2b2 = r2b2 | (0xff & bitmask[ibit]);
1902 r1b2 = r1b2 | (0xff & bitmask[ibit]);
1903 r2b1 = r2b1 | (0xff & bitmask[ibit]);
1908 r1b1 = r1b1 | (0xff & bitmask[ibit]);
1909 r2b1 = r2b1 | (0xff & bitmask[ibit]);
1913 r1b2 = r1b2 | (0xff & bitmask[ibit]);
1914 r2b2 = r2b2 | (0xff & bitmask[ibit]);
1921 r1b1 = r1b1 | (0xff & bitmask[ibit]);
1923 r1b2 = r1b2 | (0xff & bitmask[ibit]);
1925 r2b1 = r2b1 | (0xff & bitmask[ibit]);
1927 r2b2 = r2b2 | (0xff & bitmask[ibit]);
1932 r1b1 = r1b1 | (0xff & bitmask[ibit]);
1933 r1b2 = r1b2 | (0xff & bitmask[ibit]);
1934 r2b1 = r2b1 | (0xff & bitmask[ibit]);
1935 r2b2 = r2b2 | (0xff & bitmask[ibit]);
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;
1946 if (m_iNumColors == 6)
1948 m_cPlaneNumber = m_cPlaneNumber % 12;
1952 m_cPlaneNumber = m_cPlaneNumber % 7;
1958 if (!input || size == 0)
1959 memset (m_SwathData[m_iNextColor][m_iNextRaster], 0, m_iImageWidth);
1961 memcpy (m_SwathData[m_iNextColor][m_iNextRaster], input, size);
1964 if (m_iBitDepth == 1 || (m_iBitDepth == 2 && iPlaneNum == 1))
1966 if (m_iNextColor == m_iNumColors)
1969 if (m_iBitDepth == 2)
1974 if (m_iRasterCount < m_sSwathHeight * m_iNumColors)
1977 if (m_bStartPageNotSent)
1980 if (err != NO_ERROR)
1984 err = ProcessSwath (size);
1986 if (m_iNextRaster >= m_sSwathHeight)
1993 DRIVER_ERROR LDLEncap::ProcessSwath (int iCurRasterSize)
1996 DRIVER_ERROR err = NO_ERROR;
1997 unsigned int start = 0;
2000 Int16 sCurSwathHeight = m_iRasterCount / m_iNumColors;
2003 m_iVertPosn += ((m_iBlankRasters) * 600 / m_iYResolution) * DEVUNITS_XBOW / 600;
2004 m_iBlankRasters = 0;
2006 iVertPosn = m_iVertPosn;
2008 BOOL bColorPresent = TRUE;
2009 BOOL bBlackPresent = TRUE;
2010 BOOL bPhotoPresent = TRUE;
2011 short sColorSize = 0;
2018 UInt32 uiSwathSize = 0;
2020 int iSwings = pPrinterXBow->m_iBytesPerSwing;
2022 if (m_iNumColors == 1)
2027 if (pPrinterXBow->ePen == BLACK_PEN)
2033 if (m_iNumColors == 3)
2038 if (m_iNumColors == 6)
2042 if (m_iNumColors == 4)
2047 if (!m_bBidirectionalPrintingOn)
2048 m_cPrintDirection = PRNDRN_LEFTTORIGHT;
2053 int iStartRaster = m_cPassNumber % (2 * m_iBitDepth);
2056 if (pPrinterXBow->m_iLdlVersion == 2)
2058 iStartRaster = 0; // Version 2 - REVISIT
2061 if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
2063 if ((m_cPassNumber % (4 * m_iBitDepth)) < (2 * m_iBitDepth))
2073 BYTE csavMask = mask;
2077 if (m_sRefCount > 64000)
2087 if (pPrinterXBow->m_iLdlVersion == 1)
2089 // 1200 dpi split into two
2090 size = GetSwathWidth (StartColor, LastColor, iCurRasterSize/* * m_iBitDepth*/);
2094 size = GetSwathWidth (StartColor, LastColor, iCurRasterSize * m_iBitDepth);
2102 // 1200 dpi split into two
2103 size = GetSwathWidth (StartColor, LastColor, iCurRasterSize/* * m_iBitDepth*/);
2107 if (bPhotoPresent && size)
2110 size = ((size/iSwings) + 1) * iSwings;
2111 if (pPrinterXBow->m_iLdlVersion == 1)
2113 RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2114 (DEVUNITS_XBOW / 600);
2118 RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2119 (DEVUNITS_XBOW / (600 * m_iBitDepth));
2122 Int16 sFirstNozzle = 1;
2123 unsigned int uSweepSize;
2124 int jDelta = m_iYResolution / pPrinterXBow->m_iColorPenResolution;
2125 jDelta *= m_iBitDepth;
2127 uiSwathSize = size * iColors * sCurSwathHeight / jDelta;
2129 uSweepSize = sCurSwathHeight * iSwings / jDelta;
2130 n = LDL_MAX_IMAGE_SIZE / (uSweepSize);
2133 if (m_iBitDepth == 2)
2134 iStartRaster = (4 - (iStartRaster+1)) % 4;
2136 if (pPrinterXBow->m_iLdlVersion == 2)
2138 iStartRaster = 0; // Collie - REVISIT
2141 sLastNozzle = sFirstNozzle - 1 + sCurSwathHeight / jDelta;
2143 BYTE *cb = m_szCompressBuf + 16; // load sweep command
2144 memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2147 // 1200 dpi split into two
2150 if (m_iYResolution > 300 && m_cPrintQuality != QUALITY_DRAFT)
2152 iOffset = (sCurSwathHeight / (4 * m_iBitDepth));
2153 iOffset = iOffset + iOffset * ((m_cPassNumber) % (4 * m_iBitDepth));
2156 BYTE cVertAlign = 0;
2160 cVertAlign = m_cPtoCVertAlign;
2163 for (ib = 0; ib < (int) m_iBitDepth; ib++)
2165 if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
2167 start = size - iSwings;
2176 err = PrintSweep (uiSwathSize, bColorPresent, FALSE, bPhotoPresent,
2177 iVertPosn+cVertAlign, LeftEdge, RightEdge, m_cPrintDirection,
2178 sFirstNozzle, sLastNozzle);
2181 i = start + ib * m_iImageWidth; // 1200 dpi split into two
2182 for (int l = 0; l < size; l += iSwings) // Collie
2184 for (int k = StartColor+1; k < LastColor; k++)
2187 for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
2189 for (int is = 0; is < iSwings; is++)
2191 *cb++ = m_SwathData[k][j][i+is] & mask;
2195 for (j = iStartRaster; j < iOffset; j += jDelta)
2197 for (int is = 0; is < iSwings; is++)
2199 *cb++ = m_SwathData[k][j][i+is] & mask;
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;
2215 for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
2217 for (int is = 0; is < iSwings; is++)
2219 *cb++ = m_SwathData[0][j][i + is] & mask;
2223 for (j = iStartRaster; j < iOffset; j += jDelta)
2225 for (int is = 0; is < iSwings; is++)
2227 *cb++ = m_SwathData[0][j][i + is] & mask;
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;
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;
2252 if (m_bBidirectionalPrintingOn)
2253 m_cPrintDirection = (m_cPrintDirection + 1) % 2;
2255 if (pPrinterXBow->m_iLdlVersion == 2) // Collie
2262 } // 1200 dpi split into two - end of for ib = 0 loop
2269 if (!bPhotoPresent && bColorPresent)
2279 if (pPrinterXBow->m_iLdlVersion == 1)
2281 // 1200 dpi split into two
2282 size = GetSwathWidth (StartColor, LastColor, iCurRasterSize/* * m_iBitDepth*/);
2286 size = GetSwathWidth (StartColor, LastColor, iCurRasterSize * m_iBitDepth);
2291 * Check if RefCount is close to overflow of 65k.
2294 if (!bPhotoPresent && bColorPresent && size)
2297 size = ((size / iSwings) + 1) * iSwings;
2299 if (pPrinterXBow->m_iLdlVersion == 1)
2301 RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2302 (DEVUNITS_XBOW / 600);
2306 RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) *
2307 (DEVUNITS_XBOW / (600 * m_iBitDepth));
2310 Int16 sFirstNozzle = 1;
2311 unsigned int uSweepSize;
2312 int jDelta = m_iYResolution / pPrinterXBow->m_iColorPenResolution;
2313 jDelta *= m_iBitDepth;
2315 uiSwathSize = size * iColors * sCurSwathHeight / jDelta;
2317 uSweepSize = sCurSwathHeight * iSwings / jDelta;
2318 n = LDL_MAX_IMAGE_SIZE / (uSweepSize);
2321 if (m_iBitDepth == 2)
2323 iStartRaster = (4 - (iStartRaster+1)) % 4;
2324 if (pPrinterXBow->m_iLdlVersion == 2)
2326 iStartRaster = m_cPassNumber % (m_iBitDepth);
2330 sLastNozzle = sFirstNozzle - 1 + sCurSwathHeight / jDelta;
2332 BYTE *cb = m_szCompressBuf + 16; // load sweep command
2333 memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2336 // 1200 dpi split into two
2339 if (m_iYResolution > 300 && m_cPrintQuality != QUALITY_DRAFT)
2341 iOffset = (sCurSwathHeight / (4 * m_iBitDepth));
2342 iOffset = iOffset + iOffset * ((m_cPassNumber) % (4 * m_iBitDepth));
2345 for (ib = 0; ib < (int) m_iBitDepth; ib++)
2347 if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
2349 start = size - iSwings;
2357 err = PrintSweep (uiSwathSize, bColorPresent, FALSE, FALSE,
2358 iVertPosn, LeftEdge, RightEdge, m_cPrintDirection,
2359 sFirstNozzle, sLastNozzle);
2362 i = start + ib * m_iImageWidth; // 1200 dpi split into two
2363 for (int l = 0; l < size; l += iSwings) // Collie
2365 for (int k = StartColor; k < LastColor; k++)
2368 for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
2370 for (int is = 0; is < iSwings; is++)
2372 *cb++ = m_SwathData[k][j][i + is] & mask;
2376 for (j = iStartRaster; j < iOffset; j += jDelta)
2378 for (int is = 0; is < iSwings; is++)
2380 *cb++ = m_SwathData[k][j][i + is] & mask;
2388 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2389 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2391 cb = m_szCompressBuf+16;
2402 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2403 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2405 cb = m_szCompressBuf+16;
2413 if (m_bBidirectionalPrintingOn)
2414 m_cPrintDirection = (m_cPrintDirection + 1) % 2;
2415 if (pPrinterXBow->m_iLdlVersion == 2) // Collie
2420 } // 1200 dpi split into two - end of for ib = 0 loop
2429 size = GetSwathWidth (0, 1, iCurRasterSize);
2432 size = ((size/iSwings) + 1) * iSwings;
2434 RightEdge = LeftEdge + (size * 8 * 600 / m_iXResolution - 1 * (600 / m_iYResolution)) * DEVUNITS_XBOW/600;
2436 if (bBlackPresent && size && m_iBitDepth != 2 &&
2437 ((m_cPassNumber % 2) == 0 || m_cPrintQuality == QUALITY_DRAFT))
2439 Int16 sLastNozzle = 0;
2440 Int16 sFirstNozzle = 1;
2443 BYTE cVertAlign = 0;
2447 cVertAlign = m_cKtoCVertAlign;
2450 if (bColorPresent && sColorSize && m_bBidirectionalPrintingOn)
2451 m_cPrintDirection = PRNDRN_RIGHTTOLEFT;
2452 if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
2454 start = size - iSwings;
2462 if (m_iYResolution == 300)
2464 uiSwathSize = ((size/iSwings) * sCurSwathHeight * iSwings * (600 * m_iBitDepth)/ m_iYResolution);
2466 if (pPrinterXBow->m_iLdlVersion == 2 && m_iNumColors != 1)
2471 err = PrintSweep (uiSwathSize, FALSE, bBlackPresent, FALSE,
2472 (iVertPosn + cVertAlign), LeftEdge, RightEdge, m_cPrintDirection, sFirstNozzle, sLastNozzle);
2477 BYTE *cb = m_szCompressBuf+16;
2478 memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2480 n = LDL_MAX_IMAGE_SIZE / (sCurSwathHeight * iSwings * 600 / m_iYResolution);
2484 if (m_iYResolution > 300 && m_cPrintQuality != QUALITY_DRAFT)
2486 iOffset = sCurSwathHeight / 4;
2487 iOffset = iOffset + iOffset * (m_cPassNumber % 4);
2490 for (int l = 0; l < size; l += iSwings) // Collie
2492 for (j = iOffset; j < sCurSwathHeight; j++)
2494 for (int is = 0; is < iSwings; is++)
2496 *cb++ = m_SwathData[0][j][i + is] & mask;
2500 for (j = 0; j < iOffset; j++)
2502 for (int is = 0; is < iSwings; is++)
2504 *cb++ = m_SwathData[0][j][i + is] & mask;
2512 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2513 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2515 cb = m_szCompressBuf+16;
2523 err = LoadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
2524 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (iSwings / 2));
2526 cb = m_szCompressBuf+16;
2531 if (m_bBidirectionalPrintingOn)
2532 m_cPrintDirection = (m_cPrintDirection + 1) % 2;
2537 if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
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)
2543 if (m_cPassNumber % 2)
2551 if ((m_cPassNumber % 4) == 0)
2552 m_iVertPosn += (DEVUNITS_XBOW / pPrinterXBow->m_iColorPenResolution);
2554 m_iRasterCount = (sCurSwathHeight - sCurSwathHeight / (4 * m_iBitDepth)) * m_iNumColors;
2558 m_iVertPosn += ((sCurSwathHeight * 4 * 600) / m_iYResolution);
2565 void LDLEncap::FillLidilHeader (void *pLidilHdr, int Command,
2566 UInt16 CmdLen, UInt16 DataLen = 0)
2570 m_szCmdBuf[0] = FRAME_SYN;
2572 m_szCmdBuf[5] = (BYTE) Command;
2574 WRITE16(m_sRefCount++);
2580 DRIVER_ERROR LDLEncap::PrintSweep (UInt32 SweepSize,
2584 Int32 VerticalPosition,
2587 char PrintDirection,
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)
2598 if (ColorPresent == FALSE)
2605 if (pPrinterXBow->m_iLdlVersion == 1)
2607 mem_needed = SIZEOF_LDLHDR
2608 + SIZEOF_LDL_PRTSWP_CMDOPT
2609 + SIZEOF_LDL_PRTSWP_OPTFLDS
2610 + SIZEOF_LDL_PRTSWP_COLROPT * colorcount
2613 if (colorcount != 0)
2614 mem_needed += SIZEOF_LDL_COLROPT_ACTIVECOLR;
2618 mem_needed = SIZEOF_LDLHDR
2619 + SIZEOF_LDL_PRTSWP_CMDOPT + 7
2620 + SIZEOF_LDL_PRTSWP_OPTFLDS
2621 + SIZEOF_LDL_PRTSWP_COLROPT + 4
2625 memset (m_szCmdBuf, 0, mem_needed);
2627 FillLidilHeader (NULL, eLDLPrintSweep, mem_needed);
2629 int index = SIZEOF_LDLHDR;
2630 if (pPrinterXBow->m_iLdlVersion == 2)
2632 m_szCmdBuf[index++] = 1; // Version number
2634 WRITE32 (SweepSize);
2635 WRITE32 (VerticalPosition);
2636 WRITE32 (m_iLeftMargin);
2637 if (pPrinterXBow->m_iLdlVersion == 1)
2639 // LIDIL First Version
2640 m_szCmdBuf[index++] = SWINGFMT_UNCOMPRSS;
2644 // LIDIL Second Version
2645 m_szCmdBuf[index++] = 1;
2647 m_szCmdBuf[index++] = PrintDirection;
2648 if (pPrinterXBow->m_iLdlVersion == 2)
2650 WRITE32 (0); // Shingle mask
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;
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)
2662 m_szCmdBuf[index++] = 1; // Number of entries in the sweep
2665 // fill in the color information
2668 m_szCmdBuf[index++] = NO_ACTIVE_COLORS;
2669 m_szCmdBuf[index++] = FRAME_SYN;
2674 // figure out what are the active colors and fill in the optional color fields.
2676 UInt16 colrpresent = 0;
2677 UInt16 colr_found=0;
2678 UInt16 colormask = 0x01;
2679 UInt16 offset = eLDLBlack;
2682 uiAffectedColors = offset;
2683 if (BlackPresent == TRUE)
2685 uiAffectedColors = 0x1;
2687 if(BlackPresent == FALSE && PhotoPresent == FALSE)
2691 uiAffectedColors |= 0x0000000e;
2693 else if (BlackPresent == FALSE && PhotoPresent == TRUE)
2695 if (ColorPresent == TRUE)
2699 uiAffectedColors |= 0x0000007e;
2703 offset = eLDLLoBlack;
2705 uiAffectedColors |= 0x00000070;
2709 int actv_colr_index = index;
2710 int iColorRes = 300;
2711 if (pPrinterXBow->m_iLdlVersion == 1)
2719 for(UInt16 i = offset; colr_found < colorcount && i < eLDLMaxColor; i++)
2722 colrpresent = colrpresent | colormask;
2724 if (pPrinterXBow->m_iLdlVersion == 2)
2726 WRITE32 (uiAffectedColors);
2729 WRITE32 (RightEdge);
2731 WRITE32 (RightEdge);
2733 if ((i == 0 && pPrinterXBow->m_iLdlVersion == 1) || (BlackPresent && pPrinterXBow->m_iLdlVersion == 2))
2736 iPrintRes = pPrinterXBow->m_iBlackPenResolution;
2740 iDataRes = iColorRes; // 300;
2741 iPrintRes = iColorRes; // 300;
2743 WRITE16 (iDataRes); // Vertical Data Resolution
2744 WRITE16 (iPrintRes); // Vertical Print Resolution
2746 if (pPrinterXBow->m_iLdlVersion == 2)
2748 WRITE16 (m_iXResolution * m_iBitDepth); // Horizontal Data Resolution // Collie
2752 WRITE16 (m_iXResolution);
2755 if (m_iXResolution == 300)
2757 WRITE16 (600); // Force 2 drop for draft mode.
2761 if (pPrinterXBow->m_iLdlVersion == 2)
2763 WRITE16 (m_iXResolution * m_iBitDepth); // Horizontal Print Resolution // Collie
2767 WRITE16 (m_iXResolution);
2770 WRITE16 (sFirstNozzle);
2771 if (sLastNozzle == 0)
2773 int iTmp = m_iRasterCount / m_iNumColors;
2774 if (pPrinterXBow->m_iLdlVersion == 2)
2776 WRITE16 (sFirstNozzle - 1 + ((iTmp * iPrintRes) / (m_iYResolution * m_iBitDepth))); // Collie
2780 WRITE16 (sFirstNozzle - 1 + ((iTmp * iPrintRes) / (m_iYResolution)))
2785 WRITE16 (sLastNozzle);
2788 m_szCmdBuf[index++] = 0; // Vertical Alignment
2789 colormask = colormask << 1;
2790 if (pPrinterXBow->m_iLdlVersion == 2)
2796 // write the active color field
2798 if (pPrinterXBow->m_iLdlVersion == 1)
2800 index = actv_colr_index;
2801 WRITE16 (colrpresent);
2805 if (pPrinterXBow->m_iLdlVersion == 2)
2807 m_szCmdBuf[index++] = 0; // # of entries in the shingle array
2809 m_szCmdBuf[index++] = FRAME_SYN;
2813 // write out the data
2814 return (pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed));
2818 DRIVER_ERROR LDLEncap::LoadSweepData (BYTE *imagedata, int imagesize)
2820 UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_LDSWPDATA_CMDOPT
2823 if(mem_needed < LDLPACKET_MINSIZE)
2825 diff = LDLPACKET_MINSIZE - mem_needed;
2826 mem_needed = LDLPACKET_MINSIZE;
2828 memset (m_szCmdBuf, 0, mem_needed);
2830 BYTE *compressed_dataptr = imagedata;
2831 UInt16 compressed_size = imagesize;
2833 #ifdef APDK_LDL_COMPRESS
2834 if (m_ldlCompressData)
2836 m_ldlCompressData->Init ((UInt16 *) (imagedata+16), imagesize);
2838 GetFrameInfo (&compressed_dataptr, &compressed_size);
2842 FillLidilHeader (NULL, eLDLLoadSweepData, mem_needed, compressed_size);
2844 int index = SIZEOF_LDLHDR;
2845 WRITE16 (imagesize);
2849 memset (m_szCmdBuf+index, 0xFF, diff);
2852 m_szCmdBuf[index++] = FRAME_SYN;
2854 memcpy (compressed_dataptr, m_szCmdBuf, 16);
2855 return (pPrinterXBow->Send (compressed_dataptr, (DWORD) compressed_size+16));
2858 LDLEncap::~LDLEncap ()
2861 // Camera change - allocation is now AllocMem instead of new
2862 // delete [] (BYTE *) m_SwathData;
2863 m_pSys->FreeMem ((BYTE *) m_SwathData);
2865 delete [] m_szCmdBuf;
2866 if (m_szCompressBuf)
2867 delete [] m_szCompressBuf;
2869 m_pSys->FreeMem ((BYTE *) piCreditCount);
2870 if (m_pbyPacketBuff)
2871 m_pSys->FreeMem ((BYTE *) m_pbyPacketBuff);
2873 m_pSys->FreeMem ((BYTE *) pbySync);
2874 #ifdef APDK_LDL_COMPRESS
2875 if (m_ldlCompressData)
2877 delete m_ldlCompressData;
2878 m_ldlCompressData = NULL;
2883 DRIVER_ERROR LDLEncap::StartJob ()
2885 DRIVER_ERROR err = NO_ERROR;
2888 BOOL bCreditInitialized = FALSE;
2889 WORD wCreditWaitCount = 0;
2892 err = pPrinterXBow->Send (pbySync, (DWORD) SYNCSIZE);
2898 // Send Sync Complete packet
2899 err = pPrinterXBow->Send (bySyncComplete, (DWORD) sizeof (bySyncComplete));
2905 // Send Reset LIDIL packet
2906 err = pPrinterXBow->Send (byResetLIDIL, (DWORD) sizeof (byResetLIDIL));
2912 if (pPrinterXBow->IOMode.bDevID)
2914 // Enable pacing, get credit packet and update credit count
2915 err = pPrinterXBow->Send (byEnablePacing, (DWORD) sizeof (byEnablePacing));
2921 while (!bCreditInitialized && wCreditWaitCount++ < CREDIT_WAIT)
2923 bCreditInitialized = UpdateState (TRUE);
2926 if (!bCreditInitialized)
2928 return SYSTEM_ERROR;
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));
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;
2949 pby = (BYTE*) &pPrinterXBow->pLDLEncap;
2952 // Go to last byte of pLDLEncap in memory, since system is little endian
2953 pby += sizeof (pPrinterXBow->pLDLEncap) - 1;
2956 for(by = 0; by < sizeof(pPrinterXBow->pLDLEncap); by++)
2959 pbyCancel[by + COMMAND_OPT_BYTE + 1] = *pby--;
2961 pbyCancel[by + COMMAND_OPT_BYTE + 1] = *pby++;
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));
2971 UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT + SIZEOF_LDLTERM;
2972 if (pPrinterXBow->m_iLdlVersion == 2)
2977 FillLidilHeader (NULL, eLDLStartJob, mem_needed);
2979 // write in the job id
2980 int index = SIZEOF_LDLHDR;
2981 m_szCmdBuf[index++] = OPERATION_STJOB;
2982 if (pPrinterXBow->IOMode.bDevID)
2984 WRITE32 ((UInt32) this);
2988 WRITE32 ((UInt32) 0xbadfad); // for deterministic testing, des
2991 if (pPrinterXBow->m_iLdlVersion == 2)
2993 WRITE32 (0); // Shingle Mask option
2996 // add in sync frame.
2997 m_szCmdBuf[index++] = FRAME_SYN;
2999 // fill in the job header and write out the generated data
3000 err = pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
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.
3013 if (m_bBidirectionalPrintingOn || m_cPrintQuality == QUALITY_NORMAL)
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);
3030 if ((pSS->FromDevice ((char *) m_szCmdBuf, (WORD *) &index)) == NO_ERROR)
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;
3046 DRIVER_ERROR LDLEncap::EndJob ()
3048 DRIVER_ERROR err = NO_ERROR;
3050 UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT + SIZEOF_LDLTERM;
3052 FillLidilHeader (NULL, eLDLEndJob, mem_needed);
3054 int index = SIZEOF_LDLHDR;
3055 m_szCmdBuf[index++] = OPERATION_ENDJOB;
3056 if (pPrinterXBow->IOMode.bDevID)
3058 WRITE32 ((UInt32) this);
3062 WRITE32 ((UInt32) 0xbadfad); // for deterministic testing, des
3065 m_szCmdBuf[index++] = FRAME_SYN;
3067 err = pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3074 err = pPrinterXBow->Send (pbySync, SYNCSIZE);
3080 // Send Sync Complete packet
3081 err = pPrinterXBow->Send (bySyncComplete, (DWORD) sizeof (bySyncComplete));
3087 // Send Reset LIDIL packet
3088 err = pPrinterXBow->Send (byResetLIDIL, (DWORD) sizeof (byResetLIDIL));
3097 DRIVER_ERROR LDLEncap::StartPage ()
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
3106 memset (m_szCmdBuf, 0, mem_needed);
3108 FillLidilHeader (NULL, eLDLLoadPage, (UInt16) mem_needed);
3110 char mediatype = MEDIATYPE_PLAIN;
3111 BYTE quality = (BYTE) QUALITYLEVEL_NORMAL;
3112 if (m_cPrintQuality == QUALITY_BEST && m_cMediaType == MEDIA_PHOTO)
3114 mediatype = MEDIATYPE_PHOTO;
3115 quality = (BYTE) QUALITYLEVEL_BEST;
3117 else if (m_cPrintQuality == QUALITY_DRAFT)
3118 quality = (BYTE) QUALITYLEVEL_DRAFT;
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;
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);
3133 WRITE32 (MEDIALD_SPEED|NEED_TO_SERVICE_PERIOD|MINTIME_BTW_SWEEP);
3135 // set up the option fields
3136 m_szCmdBuf[index++] = 4; // MediaLoadSpeed;
3137 m_szCmdBuf[index++] = 0; // NeedToServicePeriod;
3138 WRITE16 (200); // MinTimeBetweenSweeps
3140 if (colorcount == 0)
3142 m_szCmdBuf[index++] = FRAME_SYN;
3145 m_bStartPageNotSent = FALSE;
3146 // write out the data
3147 return (pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed));
3150 DRIVER_ERROR LDLEncap::Continue ()
3153 UInt16 mem_needed = SIZEOF_LDLHDR + 1
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));
3168 void LDLEncap::Cancel ()
3171 UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT
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);
3187 DRIVER_ERROR LDLEncap::CleanPen ()
3190 UInt16 mem_needed = SIZEOF_LDLHDR + 1 + 2
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);
3209 DRIVER_ERROR LDLEncap::EndPage ()
3212 DRIVER_ERROR err = NO_ERROR;
3214 int iCurNumRasters = m_iRasterCount;
3215 if ((m_cPrintQuality == QUALITY_DRAFT || m_iYResolution == 300) && m_iRasterCount)
3217 else if (m_cPrintQuality != QUALITY_DRAFT)
3219 icount = 4 * m_iBitDepth;
3220 iCurNumRasters = m_sSwathHeight * m_iNumColors;
3224 n = m_sSwathHeight / (4 * m_iBitDepth);
3226 n = n * (m_cPassNumber + 1) - m_iNextRaster;
3227 for (i = 0; i < m_iNumColors; i++)
3229 for (j = 0; j < n; j++)
3230 memset (m_SwathData[i][m_iNextRaster+j], 0, m_iImageWidth * m_iBitDepth);
3233 n = m_sSwathHeight / (4 * m_iBitDepth);
3237 m_iRasterCount = iCurNumRasters;
3238 err = ProcessSwath (m_iImageWidth);
3239 if (err != NO_ERROR)
3242 if (m_iNextRaster >= m_sSwathHeight)
3244 for (i = 0; i < m_iNumColors; i++)
3246 for (j = 0; j < n; j++)
3247 memset (m_SwathData[i][m_iNextRaster+j], 0, m_iImageWidth * m_iBitDepth);
3252 UInt16 mem_needed = SIZEOF_LDLHDR
3253 + SIZEOF_LDL_EJPAGE_CMDOPT
3254 + SIZEOF_LDL_EJPAGE_OPTFLDS
3257 memset (m_szCmdBuf, 0, mem_needed);
3258 FillLidilHeader(NULL, eLDLEjectPage, mem_needed);
3260 int index = SIZEOF_LDLHDR;
3261 WRITE32 (MEDIA_EJSPEED);
3263 m_szCmdBuf[index++] = 15;
3264 m_szCmdBuf[index++] = FRAME_SYN;
3268 err = pPrinterXBow->Send (m_szCmdBuf, (DWORD) mem_needed);
3272 m_iBlankRasters = 0;
3273 m_iVertPosn = (int) (m_pthisPC->PrintableStartY () * DEVUNITS_XBOW);
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,
3286 &fXOverSpray, &fYOverSpray,
3287 &fLeftOverSpray, &fTopOverSpray))
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.
3298 m_iVertPosn = (int) (-fTopOverSpray * DEVUNITS_XBOW);
3301 if (/*m_iYResolution != 300*/m_cPrintQuality != QUALITY_DRAFT)
3302 m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / 4) * m_iNumColors;
3304 m_bStartPageNotSent = TRUE;
3306 if (m_cPrintQuality != QUALITY_DRAFT && m_iYResolution != 300)
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);
3313 if (m_pthisPC->bDoFullBleed &&
3314 pPrinterXBow->FullBleedCapable (m_pthisPC->thePaperSize,
3316 &fXOverSpray, &fYOverSpray,
3317 &fLeftOverSpray, &fTopOverSpray))
3319 if (m_iVertPosn < -850) m_iVertPosn = -850;
3323 if (m_iVertPosn < -600) m_iVertPosn = -600;
3325 if (m_iBitDepth == 2)
3328 for (i = 0; i < m_iNumColors; i++)
3330 for (int j = 0; j < m_sSwathHeight; j++)
3332 memset (m_SwathData[i][j], 0, m_iImageWidth);
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.
3351 * Author: Don Castrapel
3354 BOOL LDLEncap::GetPackets(DWORD &dwBytesRead)
3356 DRIVER_ERROR err = NO_ERROR;
3357 DWORD dwReadSize = 0;
3358 WORD wPacketWaitCount = 0;
3359 BYTE *pbyPacketBuff = NULL;
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)
3371 m_pSys->FreeMem ((BYTE *) m_pbyPacketBuff);
3372 m_pbyPacketBuff = NULL;
3373 m_dwPacketBuffSize = 0;
3376 memset(m_pbyPacketBuff, 0, MAX_PACKET_READ_SIZE);
3380 while(!dwBytesRead && wPacketWaitCount++ < PACKET_WAIT)
3382 if(m_pSys->BusyWait((DWORD)100) == JOB_CANCELED)
3387 dwReadSize = MAX_PACKET_READ_SIZE;
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)
3396 break; // Out of do loop
3399 // FromDevice resets dwReadSize to the number of bytes read from the port
3400 dwReadSize = MAX_PACKET_READ_SIZE;
3402 if(!m_pbyPacketBuff)
3404 // First read, allocate buffer to hold data
3405 m_pbyPacketBuff = m_pSys->AllocMem(MAX_PACKET_READ_SIZE);
3406 if(!m_pbyPacketBuff)
3410 memset(m_pbyPacketBuff, 0, MAX_PACKET_READ_SIZE);
3411 m_dwPacketBuffSize = MAX_PACKET_READ_SIZE;
3413 else if(dwBytesRead)
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);
3425 m_dwPacketBuffSize += MAX_PACKET_READ_SIZE;
3426 memset(pbyPacketBuff, 0, m_dwPacketBuffSize);
3428 memcpy(pbyPacketBuff, m_pbyPacketBuff, dwBytesRead);
3431 m_pSys->FreeMem((BYTE *)m_pbyPacketBuff);
3432 m_pbyPacketBuff = NULL;
3435 m_pbyPacketBuff = pbyPacketBuff;
3438 err = m_pSys->FromDevice((m_pbyPacketBuff + dwBytesRead), &dwReadSize);
3443 dwBytesRead += dwReadSize;
3444 } while(!err && dwReadSize);
3445 } // while(!dwBytesRead && wPacketWaitCount++ < PACKET_WAIT)
3449 // No data to read from port
3457 * Author: Don Castrapel
3460 BOOL LDLEncap::UpdateState(BOOL bInitialize)
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;
3474 // Read packets from port
3475 bPacketsReceived = GetPackets(dwBytesRead);
3476 if(!bPacketsReceived)
3481 while(dwBytesProcessed < dwBytesRead)
3483 if(m_pbyPacketBuff[dwBytesProcessed] != '$')
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];
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).
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.
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)
3511 case ABSOLUTE_CREDIT:
3514 // Get number of commands to allocate memory for CreditCount buffer.
3515 // Byte 11(byReadBuff[10])
3516 byNumberOfCommands = m_pbyPacketBuff[NUMBER_OF_COMMANDS_BYTE];
3520 m_pSys->FreeMem((BYTE*)piCreditCount);
3523 (short int *)(m_pSys->AllocMem(sizeof(short int) * byNumberOfCommands));
3528 memset(piCreditCount, 0, (sizeof(short int) * byNumberOfCommands));
3531 for(by = 0; by < byNumberOfCommands; by++)
3533 piCreditCount[by] = (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + dwBytesProcessed] << 8) |
3534 (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + 1 + dwBytesProcessed]);
3537 bUpdatedState = TRUE;
3541 case INCREMENTAL_CREDIT:
3544 // If we're initializing we must wait for an absolute credit packet
3548 for(by = 0; by < byNumberOfCommands; by++)
3550 piCreditCount[by] += (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + dwBytesProcessed] << 8) |
3551 (m_pbyPacketBuff[by * 2 + CREDIT_BYTE + 1 + dwBytesProcessed]);
3554 bUpdatedState = TRUE;
3558 /* case RESPONSE_COMMAND_EXECUTED:
3561 // If we're initializing we must wait for an absolute credit packet
3565 // We should only get command number 5, which is the Query command
3566 switch(byCommandNumber)
3569 // Copy status into LDLEncap's status buffer
3570 memcpy(byStatusBuff, (m_pbyPacketBuff + dwBytesProcessed),
3571 (wCommandLength + wDataLength));
3578 } // switch(byCommandNumber)
3585 // If we're initializing we must wait for an absolute credit packet
3589 // We should only get reference number 1, which is what I set up for the
3590 // EOCStatusQuery command
3591 switch(wReferenceNumber)
3593 case AUTO_RESPONSE_STATUS:
3595 // Copy status into LDLEncap's status buffer
3596 memcpy(byStatusBuff, (m_pbyPacketBuff + dwBytesProcessed),
3597 (wCommandLength + wDataLength));
3599 bUpdatedState = TRUE;
3606 } // switch(wReferenceNumber)
3613 // If we're initializing we must wait for an absolute credit packet
3619 } // switch(byPacketType)
3621 dwBytesProcessed += (DWORD)(wCommandLength + wDataLength);
3622 } // while(dwBytesProcessed < dwBytesRead)
3624 return bUpdatedState;
3627 #ifdef APDK_LDL_COMPRESS
3630 * Compression Related
3635 ///////////////////////////////////////////////////////////////////////
3637 ///////////////////////////////////////////////////////////////////////
3639 UInt16 LDLEncap::FlushImage ()
3647 wsize = m_ldlCompressData->image_cnt;
3652 from_ptr = m_ldlCompressData->image_ptr;
3654 command = FILL_IMAGE_CMD | (wsize-1);
3658 if (m_bLittleEndian)
3660 *m_ldlCompressData->out_ptr++ = (((UInt16) m_szCmdBuf[1]) << 8) | m_szCmdBuf[0];
3664 *m_ldlCompressData->out_ptr++ = command;
3667 memcpy (m_ldlCompressData->out_ptr, from_ptr, sizeof (UInt16) * wsize);
3668 m_ldlCompressData->out_ptr += wsize;
3670 for (UInt16 i = 0; i < wsize; i++)
3672 *m_ldlCompressData->out_ptr++ = *from_ptr++;
3674 bsize = ((m_ldlCompressData->image_cnt+1) * 2);
3675 m_ldlCompressData->out_cnt += bsize;
3677 m_ldlCompressData->image_cnt = 0;
3683 ///////////////////////////////////////////////////////////////////////
3685 ///////////////////////////////////////////////////////////////////////
3686 UInt16 LDLEncap::FlushCopy (UInt16 value)
3693 size = m_ldlCompressData->copy_cnt;
3697 UInt16 *uP = m_ldlCompressData->out_ptr++;
3701 command = FILL_0000_CMD | (m_ldlCompressData->copy_cnt-1);
3703 else if (value == 0xFFFF)
3705 command = FILL_FFFF_CMD | (m_ldlCompressData->copy_cnt-1);
3709 command = FILL_NEXT_CMD | (m_ldlCompressData->copy_cnt-1);
3712 *m_ldlCompressData->out_ptr++ = value;
3713 // *m_ldlCompressData->out_ptr++ = (((UInt16) m_szCmdBuf[1]) << 8) | m_szCmdBuf[0];
3719 if (m_bLittleEndian)
3721 *uP = (((UInt16) m_szCmdBuf[1]) << 8) | m_szCmdBuf[0];
3728 m_ldlCompressData->out_cnt += size;
3729 m_ldlCompressData->copy_cnt = 0;
3734 ///////////////////////////////////////////////////////////////////////
3736 ///////////////////////////////////////////////////////////////////////
3737 void LDLEncap::CompressData (Int16 compressionmode)
3746 LDLCOMPMODE mode = IN_NOT;
3749 m_ldlCompressData->out_cnt = 0;
3750 m_ldlCompressData->image_cnt = 0;
3751 m_ldlCompressData->copy_cnt = 0;
3753 m_ldlCompressData->out_ptr = &m_ldlCompressData->out_array[8];
3754 data_length = m_ldlCompressData->data_length;
3756 if ((data_length & 1) != 0)
3758 // ErrorTrap((char *)"Data length is odd.");
3762 in_ptr = &m_ldlCompressData->raw_data[0];
3764 for (i=0; i<data_length; i+=2)
3772 /* default the first entry to 'image' */
3774 m_ldlCompressData->image_ptr = in_ptr;
3775 m_ldlCompressData->image_cnt = 1;
3782 #if ALLOW_FILL_NEXT_CMD
3785 if ((last == in) && ((in==0xFFFF) || (in == 0)) )
3789 m_ldlCompressData->copy_cnt = 2;
3790 m_ldlCompressData->image_cnt = 0;
3796 m_ldlCompressData->image_cnt++;
3806 m_ldlCompressData->copy_cnt++;
3810 /* revisit - could allow 2 words of copy if the data is
3813 /* convert a copy cnt of 2 to an image */
3814 UInt16 copy_count = m_ldlCompressData->copy_cnt;
3816 if (copy_count <= m_ldlCompressData->run_length)
3818 if (m_ldlCompressData->image_cnt == 0)
3820 /* point the pointer to the first element */
3821 m_ldlCompressData->image_ptr = in_ptr - copy_count;
3823 m_ldlCompressData->image_cnt += (1+copy_count);
3824 m_ldlCompressData->copy_cnt = 0;
3828 /* have enough to be a legal copy */
3830 (void) FlushImage ();
3832 (void) FlushCopy (copy_item);
3834 m_ldlCompressData->image_ptr = in_ptr;
3835 m_ldlCompressData->image_cnt = 1;
3845 #if ALLOW_FILL_NEXT_CMD
3848 if ((last == in) && ((in==0xFFFF) || (in == 0)) )
3851 m_ldlCompressData->image_cnt--;
3855 m_ldlCompressData->copy_cnt = 2;
3857 else /* different */
3860 m_ldlCompressData->image_cnt++;
3871 } /* next data - end of processing */
3873 /* flush out the remainder */
3879 /* have enough to be a legal copy */
3880 (void) FlushImage ();
3882 (void) FlushCopy (copy_item);
3888 (void) FlushImage ();
3895 if (m_ldlCompressData->out_cnt > 2048+16)
3897 // ErrorTrap("out cnt too big");
3902 /////////////////////////////////////////////////////////////////////////////////
3904 /////////////////////////////////////////////////////////////////////////////////
3905 BOOL LDLEncap::GetFrameInfo (BYTE **outdata, UInt16 *data_size)
3907 *outdata = (unsigned char *) &m_ldlCompressData->out_array[0];
3908 *data_size = m_ldlCompressData->out_cnt;
3912 /////////////////////////////////////////////////////////////////////////////////
3913 //Init: to init/reinit the data structure.
3914 /////////////////////////////////////////////////////////////////////////////////
3915 BOOL comp_ptrs_t::Init (UInt16 *data, UInt16 datasize)
3919 data_length = datasize;
3921 run_length = MAX_RUNLENGTH;
3926 #endif // APDK_LDL_COMPRESS
3930 #endif // APDK_DJ3320