Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpcups / Lidil.cpp
1 /*****************************************************************************\
2   Lidil.cpp : Implementation of Lidil class
3
4   Copyright (c) 1996 - 2009, 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 #include "CommonDefinitions.h"
32 #include "Encapsulator.h"
33 #include "LidilCompress.h"
34 #include "Lidil.h"
35 #include "ColorMatcher.h"
36 #include "Halftoner.h"
37 #include "resources.h"
38 #include "ColorMaps.h"
39 #include "LidilPrintModes.h"
40 #include "PrinterCommands.h"
41
42 typedef union
43 {
44     Int32    int_value;
45     char     char_val[4];
46 } Int32Bytes;
47
48 typedef union
49 {
50     Int16    int_value;
51     char     char_val[2];
52 } Int16Bytes;
53
54 Lidil::Lidil() : Encapsulator()
55 {
56     m_pPM = NULL;
57     m_lidil_version = 1;
58     m_iBytesPerSwing = 2;
59     m_iColorPenResolution = 300;
60     m_iBlackPenResolution = 1200;
61     m_iNumBlackNozzles    = 400;
62     m_cPrintDirection = PRNDRN_LEFTTORIGHT;
63     m_SwathData = NULL;
64     m_sRefCount = 6;
65     m_iBlankRasters = 0;
66     m_iRasterCount = 0;
67     m_iNextRaster = 0; 
68     m_iNextColor  = 0;
69     m_iBitDepth = 1;
70     m_bBidirectionalPrintingOn = true;
71     m_cKtoCVertAlign = 12;
72     m_cPtoCVertAlign = 6;
73     m_pLidilCompress = NULL;
74     m_szCompressBuf  = NULL;
75     Int16Bytes    val;
76     val.int_value = 0x0102;
77     if (val.char_val[0] == 0x01)
78         m_bLittleEndian = false;
79     else
80         m_bLittleEndian = true;
81 }
82
83 Lidil::~Lidil()
84 {
85     if (m_pLidilCompress)
86         delete m_pLidilCompress;
87     if (m_SwathData)
88         delete [] m_SwathData;
89     if (m_szCompressBuf)
90         delete [] m_szCompressBuf;
91 }
92
93 DRIVER_ERROR Lidil::Configure(Pipeline **pipeline)
94 {
95     Pipeline    *p = NULL;
96     Pipeline    *head;
97     unsigned int width;
98     ColorMatcher *pColorMatcher;
99     int          iRows[MAXCOLORPLANES];
100     unsigned int uiResBoost;
101     head = *pipeline;
102
103     if (m_pPM->BaseResX != m_pQA->horizontal_resolution ||
104         m_pPM->BaseResY != m_pQA->vertical_resolution)
105     {
106         dbglog("Requested resolution not supported with requested printmode");
107         return UNSUPPORTED_PRINTMODE;
108     }
109
110     for (int i = 0; i < MAXCOLORPLANES; i++)
111     {
112         iRows[i] = m_pPM->ResolutionX[i] / m_pPM->BaseResX;
113     }
114     uiResBoost = m_pPM->BaseResX / m_pPM->BaseResY;
115     if (uiResBoost == 0)
116         uiResBoost = 1;
117
118     width = m_pMA->printable_width;
119
120     pColorMatcher = new ColorMatcher(m_pPM->cmap, m_pPM->dyeCount, width);
121     head = new Pipeline(pColorMatcher);
122     Halftoner    *pHalftoner;
123     pHalftoner = new Halftoner (m_pPM, width, iRows, uiResBoost, m_pPM->eHT == MATRIX);
124     p = new Pipeline(pHalftoner);
125     head->AddPhase(p);
126
127     *pipeline = head;
128     return NO_ERROR;
129 }
130
131 DRIVER_ERROR Lidil::StartJob(SystemServices *pSystemServices, JobAttributes *pJA)
132 {
133     DRIVER_ERROR    err = NO_ERROR;
134     m_pSystemServices = pSystemServices;
135
136     m_pJA = pJA;
137     m_pMA = &pJA->media_attributes;
138     m_pQA = &pJA->quality_attributes;
139
140     if (!strcmp(m_pJA->printer_platform, "dj4100"))
141     {
142         m_lidil_version = 2;
143         m_iBytesPerSwing = 4;
144         m_iColorPenResolution = 600;
145     }
146     else if (!strcmp(m_pJA->printer_platform, "dj2600"))
147     {
148         m_lidil_version = 2;
149         m_iBytesPerSwing = 4;
150         m_iColorPenResolution = 600;
151         m_iBlackPenResolution = 600;
152         m_iNumBlackNozzles = 336;
153     }
154     if (m_pQA->print_quality == BEST_QUALITY && m_pQA->media_type == MEDIATYPE_PHOTO)
155     {
156         m_iBitDepth = 2;
157     }
158     cur_pcl_buffer_size = PCL_BUFFER_SIZE;
159     pcl_buffer = new BYTE[cur_pcl_buffer_size + 2];
160     if (pcl_buffer == NULL)
161     {
162         return ALLOCMEM_ERROR;
163     }
164     memset(pcl_buffer, 0, cur_pcl_buffer_size);
165     cur_pcl_buffer_ptr = pcl_buffer;
166
167     if (!selectPrintMode())
168     {
169         dbglog("selectPrintMode failed, PrintMode name = %s", m_pQA->print_mode_name);
170         return UNSUPPORTED_PRINTMODE;
171     }
172     
173     
174     if (m_pPM->BaseResX != m_pQA->horizontal_resolution ||
175         m_pPM->BaseResY != m_pQA->vertical_resolution)
176     {
177         dbglog("Requested resolution not supported with requested printmode");        
178                 dbglog(" m_pPM->BaseResX = %d\n",m_pPM->BaseResX);
179                 dbglog(" m_pPM->BaseResY = %d\n",m_pPM->BaseResY);
180                 dbglog(" m_pQA->horizontal_resolution = %d\n",m_pQA->horizontal_resolution);
181                 dbglog(" m_pQA->vertical_resolution = %d\n",m_pQA->vertical_resolution);    
182         return UNSUPPORTED_PRINTMODE;
183     }
184
185     m_iVertPosn = (m_pMA->printable_start_y * DEVUNITS_XBOW) / m_pQA->vertical_resolution;
186     m_iLeftMargin = (m_pMA->printable_start_x * DEVUNITS_XBOW) / m_pQA->vertical_resolution;
187     if (m_pJA->print_borderless)
188     {
189         m_iVertPosn = (-m_pMA->vertical_overspray * DEVUNITS_XBOW) / (2 * m_pQA->vertical_resolution);
190         m_iLeftMargin = (-m_pMA->horizontal_overspray * DEVUNITS_XBOW) / (2 * m_pQA->horizontal_resolution);
191     }
192
193     err = allocateSwathBuffers();
194     if (err != NO_ERROR)
195     {
196         dbglog("allocateSwathBuffers failed, err = %d", err);
197         return err;
198     }
199
200     addToHeader(LdlSync, sizeof(LdlSync));
201     cur_pcl_buffer_ptr[SYNC_CMD_OPT_SIZE] = FRAME_SYN;
202     err = m_pSystemServices->Send(pcl_buffer, SYNCSIZE);
203     cur_pcl_buffer_ptr = pcl_buffer;
204     addToHeader(LdlSyncComplete, sizeof(LdlSyncComplete));
205     addToHeader(LdlReset, sizeof(LdlReset));
206     UInt16    mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT + SIZEOF_LDLTERM;
207     if (m_lidil_version == 2)
208     {
209         mem_needed += 4;
210     }
211     fillLidilHeader(NULL, eLDLStartJob, mem_needed);
212     *cur_pcl_buffer_ptr++ = OPERATION_STJOB;
213     addInt32(m_pJA->job_id);
214     if (m_lidil_version == 2)
215         addInt32(0);
216     *cur_pcl_buffer_ptr++ = FRAME_SYN;
217     err = Cleanup();
218
219 //    m_pLidilCompress = new LidilCompress(m_bLittleEndian);
220     return err;
221 }
222
223 DRIVER_ERROR Lidil::EndJob()
224 {
225     DRIVER_ERROR    err = NO_ERROR;
226     UInt16    mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT + SIZEOF_LDLTERM;
227     Cleanup();
228     memset(pcl_buffer, 0, cur_pcl_buffer_size);
229     fillLidilHeader(NULL, eLDLEndJob, mem_needed);
230     *cur_pcl_buffer_ptr++ = OPERATION_ENDJOB;
231     addInt32(m_pJA->job_id);
232     *cur_pcl_buffer_ptr++ = FRAME_SYN;
233     addToHeader(LdlSync, sizeof(LdlSync));
234     cur_pcl_buffer_ptr += SYNC_CMD_OPT_SIZE;
235     *cur_pcl_buffer_ptr++ = FRAME_SYN;
236     cur_pcl_buffer_ptr = pcl_buffer + SYNCSIZE + mem_needed;
237     addToHeader(LdlSyncComplete, sizeof(LdlSyncComplete));
238     addToHeader(LdlReset, sizeof(LdlReset));
239     err = Cleanup();
240     return err;
241 }
242
243 void Lidil::CancelJob()
244 {
245     UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_JOB_CMDOPT
246                         + SIZEOF_LDLTERM;
247     fillLidilHeader (NULL, eLDLControl, mem_needed);
248     addInt32 (m_pJA->job_id);
249     *cur_pcl_buffer_ptr++ = OPERATION_CANCJOB;
250     *cur_pcl_buffer_ptr++ = FRAME_SYN;
251     Cleanup();
252 }
253
254 DRIVER_ERROR Lidil::StartPage(JobAttributes *pJA)
255 {
256     DRIVER_ERROR    err = NO_ERROR;
257     m_pJA = pJA;
258     m_pMA = &pJA->media_attributes;
259     m_pQA = &pJA->quality_attributes;
260     UInt32 mem_needed = SIZEOF_LDLHDR  + SIZEOF_LDL_LDPAGE_CMDOPT
261                                        + SIZEOF_LDL_LDPAGE_OPTFLDS
262                                        + SIZEOF_LDLTERM;
263
264     memset (cur_pcl_buffer_ptr, 0, mem_needed);
265
266     fillLidilHeader (NULL, eLDLLoadPage, (UInt16) mem_needed);
267     *cur_pcl_buffer_ptr++ = m_pQA->media_type;;
268     *cur_pcl_buffer_ptr++ = MEDIASRC_MAINTRAY;
269     *cur_pcl_buffer_ptr++ = MEDIADEST_MAINBIN;
270     *cur_pcl_buffer_ptr++ = m_pQA->print_quality;
271     *cur_pcl_buffer_ptr++ = SPECLOAD_NONE;
272
273     addInt32((Int32) (m_pMA->physical_width * DEVUNITS_XBOW / m_pQA->horizontal_resolution));
274     addInt32((Int32) (m_pMA->physical_height * DEVUNITS_XBOW / m_pQA->vertical_resolution));
275
276     addInt32(MEDIALD_SPEED|NEED_TO_SERVICE_PERIOD|MINTIME_BTW_SWEEP);
277
278     // set up the option fields
279     *cur_pcl_buffer_ptr++ = 4; // MediaLoadSpeed;
280     *cur_pcl_buffer_ptr++ = 0; // NeedToServicePeriod;
281     addInt16 (200);           // MinTimeBetweenSweeps
282
283     *cur_pcl_buffer_ptr++ = FRAME_SYN;
284     err = Cleanup ();
285     return err;
286 }
287
288 DRIVER_ERROR Lidil::SendCAPy(int iOffset)
289 {
290     DRIVER_ERROR    err = NO_ERROR;
291 #if 0
292     if (m_iRasterCount == 0)
293     {
294         m_iBlankRasters += iOffset;
295         return err;
296     }
297 #endif
298     int     iCount = m_pPM->dyeCount * m_iBitDepth;
299     if (m_iBitDepth == 2 && m_pPM->dyeCount != 6)
300         iCount++;
301
302     RASTERDATA    rasterdata;
303     memset(&rasterdata, 0, sizeof(rasterdata));
304     while (iOffset > 0)
305     {
306         for (int i = 0; i < iCount; i++)
307         {
308             err = Encapsulate (&rasterdata, 0);
309             ERRCHECK;
310         }
311         iOffset--;
312     }
313     return err;
314 }
315
316 DRIVER_ERROR Lidil::FormFeed()
317 {
318     DRIVER_ERROR    err = NO_ERROR;
319     int icount = 0;
320     int iCurNumRasters = m_iRasterCount;
321     if ((m_pQA->print_quality == DRAFT_QUALITY || m_pQA->vertical_resolution == 300) && m_iRasterCount)
322         icount = 1;
323     else if (m_pQA->print_quality != DRAFT_QUALITY)
324     {
325         icount = 4 * m_iBitDepth;
326         iCurNumRasters = m_sSwathHeight * m_pPM->dyeCount;
327     }
328
329     int i, j, n;
330     n = m_sSwathHeight / (4 * m_iBitDepth);
331
332     n = n * (m_cPassNumber + 1) - m_iNextRaster;
333     for (i = 0; i < (int) m_pPM->dyeCount; i++)
334     {
335         for (j = 0; j < n; j++)
336             memset (m_SwathData[i][m_iNextRaster+j], 0, m_iImageWidth * m_iBitDepth);
337     }
338     m_iNextRaster += n;
339     n = m_sSwathHeight / (4 * m_iBitDepth);
340
341     while (icount)
342     {
343         m_iRasterCount = iCurNumRasters;
344         err = processSwath ();
345         if (err != NO_ERROR)
346             break;
347         icount--;
348         if (m_iNextRaster >= m_sSwathHeight)
349             m_iNextRaster = 0;
350         for (i = 0; i < (int) m_pPM->dyeCount; i++)
351         {
352             for (j = 0; j < n; j++)
353                 memset (m_SwathData[i][m_iNextRaster+j], 0, m_iImageWidth * m_iBitDepth);
354         }
355         m_iNextRaster += n;
356     }
357
358     UInt16 mem_needed = SIZEOF_LDLHDR
359                         + SIZEOF_LDL_EJPAGE_CMDOPT
360                         + SIZEOF_LDL_EJPAGE_OPTFLDS
361                         + SIZEOF_LDLTERM;
362
363     fillLidilHeader(NULL, eLDLEjectPage, mem_needed);
364
365     addInt32 (MEDIA_EJSPEED);
366
367     *cur_pcl_buffer_ptr++ = 15;
368     *cur_pcl_buffer_ptr++ = FRAME_SYN;
369     if(err == NO_ERROR)
370     {
371         err = Cleanup();
372     }
373
374     m_sRefCount = 6;
375     m_iBlankRasters = 0;
376     m_iVertPosn = (m_pMA->printable_start_y * DEVUNITS_XBOW) / m_pQA->vertical_resolution;
377     m_iRasterCount = 0;
378     m_iNextRaster = 0;
379     m_iNextColor  = 0;
380
381     if (m_pJA->print_borderless)
382     {
383         m_iVertPosn = (int) (-m_pMA->vertical_overspray * DEVUNITS_XBOW) / (2 * m_pQA->vertical_resolution);
384     }
385
386     if (m_pQA->print_quality != DRAFT_QUALITY)
387         m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / 4) * m_pPM->dyeCount;
388
389     if (m_pQA->print_quality == DRAFT_QUALITY && m_pQA->vertical_resolution != 300)
390     {
391         m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * m_pPM->dyeCount;
392         m_iVertPosn -= (((m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * 600 / m_pQA->vertical_resolution) * DEVUNITS_XBOW / 600);
393     }
394     m_cPassNumber = 0;
395
396     if (m_pJA->print_borderless)
397     {
398         if (m_iVertPosn < -850) m_iVertPosn = -850;
399     }
400     else
401     {
402         if (m_iVertPosn < -600) m_iVertPosn = -600;
403     }
404     if (m_iBitDepth == 2)
405         m_iVertPosn += 6;
406
407     for (i = 0; i < (int) m_pPM->dyeCount; i++)
408     {
409         for (int j = 0; j < m_sSwathHeight; j++)
410         {
411             memset (m_SwathData[i][j], 0, m_iImageWidth);
412         }
413     }
414
415     return err;
416 }
417
418 DRIVER_ERROR Lidil::Encapsulate(RASTERDATA *InputRaster, bool bLastPlane)
419 {
420     DRIVER_ERROR    err = NO_ERROR;
421     int iPlaneNum = 0;
422     if (m_iBitDepth == 2)
423     {
424         if (m_pPM->dyeCount != 6)
425         {
426             if (m_cPlaneNumber == 0)
427             {
428                 m_cPlaneNumber++;
429                 return NO_ERROR;
430             }
431         }
432         int iCPlane;
433         if (m_pPM->dyeCount == 6)
434         {
435             iPlaneNum = m_cPlaneNumber % 2;
436         }
437         else
438         {
439             iPlaneNum = (m_cPlaneNumber + 1) % 2;
440         }
441         int iRowNum = (m_iRasterCount / 6) * 2 + iPlaneNum;
442         iRowNum = m_iNextRaster;
443         if (m_pPM->dyeCount == 6)
444         {
445             iCPlane = m_cPlaneNumber / 2;
446         }
447         else
448         {
449             iCPlane = (m_cPlaneNumber - 1) / 2;
450         }
451         if (iPlaneNum == 0)
452         {
453             if (!InputRaster->rasterdata[COLORTYPE_COLOR])
454             {
455                 m_bPrevRowWasBlank = true;
456                 memset (m_SwathData[iCPlane][iRowNum], 0, m_iImageWidth * 2);
457             }
458             else
459             {
460                 m_bPrevRowWasBlank = false;
461                 memcpy (m_SwathData[iCPlane][iRowNum], InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR]);
462             }
463         }
464         if (m_pPM->dyeCount == 6)
465         {
466             m_cPlaneNumber = (m_cPlaneNumber + 1) % 12;
467         }
468         else
469         {
470             m_cPlaneNumber = (m_cPlaneNumber + 1) % 8;
471         }
472
473         if (iPlaneNum == 1)
474         {
475             if (InputRaster->rasterdata[COLORTYPE_COLOR] || !m_bPrevRowWasBlank)
476             {
477                 applyShingleMask(iCPlane, InputRaster->rasterdata[COLORTYPE_COLOR]);
478             }
479             else
480             {
481                 memset (m_SwathData[iCPlane][m_iNextRaster+1], 0, m_iImageWidth * 2);
482             }
483
484             if (m_pPM->dyeCount == 6)
485             {
486                 m_cPlaneNumber = m_cPlaneNumber % 12;
487             }
488             else
489             {
490                 m_cPlaneNumber = m_cPlaneNumber % 7;
491             }
492         }
493     }
494     else
495     {
496         if (InputRaster->rasterdata[COLORTYPE_COLOR] == NULL)
497             memset (m_SwathData[m_iNextColor][m_iNextRaster], 0, m_iImageWidth);
498         else
499             memcpy (m_SwathData[m_iNextColor][m_iNextRaster], InputRaster->rasterdata[COLORTYPE_COLOR], m_iImageWidth);
500     }
501     m_iRasterCount++;
502     if (m_iBitDepth == 1 || (m_iBitDepth == 2 && iPlaneNum == 1))
503         m_iNextColor++;
504     if (m_iNextColor == (int) m_pPM->dyeCount)
505     {
506         m_iNextColor = 0;
507         if (m_iBitDepth == 2)
508             m_iNextRaster += 2;
509         else
510             m_iNextRaster++;
511     }
512     if (m_iRasterCount < (int) (m_sSwathHeight * m_pPM->dyeCount))
513         return NO_ERROR;
514
515     err = processSwath ();
516
517     if (m_iNextRaster >= m_sSwathHeight)
518     {
519         m_iNextRaster = 0;
520     }
521     return err;
522 }
523
524 void    Lidil::fillLidilHeader(void *pLidilHdr, int Command, UInt16 CmdLen, UInt16 DataLen)
525 {
526     memset(cur_pcl_buffer_ptr, 0, SIZEOF_LDLHDR);
527     *cur_pcl_buffer_ptr++ = FRAME_SYN;
528     addInt16(CmdLen);
529     cur_pcl_buffer_ptr += 2;
530     *cur_pcl_buffer_ptr++ = (BYTE) Command;
531     addInt16(m_sRefCount++);
532     addInt16(DataLen);
533 }
534
535 void    Lidil::addInt32(Int32    iVal)
536 {
537     Int32Bytes    val;
538     val.int_value = iVal;
539     if (m_bLittleEndian)
540     {
541         for (int i = 3; i > -1; i--)
542         *cur_pcl_buffer_ptr++ = val.char_val[i];
543     }
544     else
545     {
546         memcpy(cur_pcl_buffer_ptr, val.char_val, 4);
547         cur_pcl_buffer_ptr += 4;
548     }
549 }
550
551 void    Lidil::addInt16(Int16    iVal)
552 {
553     Int16Bytes    val;
554     val.int_value = iVal;
555     if (m_bLittleEndian)
556     {
557         *cur_pcl_buffer_ptr++ = val.char_val[1];
558     *cur_pcl_buffer_ptr++ = val.char_val[0];
559     }
560     else
561     {
562         memcpy(cur_pcl_buffer_ptr, val.char_val, 2);
563         cur_pcl_buffer_ptr += 2;
564     }
565 }
566
567
568 bool Lidil::selectPrintMode(int index)
569 {
570     PrintMode    *p = lidil_print_modes_table[index].print_modes;
571     int iPMIndex = 0; 
572     
573     if (!strcmp(m_pJA->printer_platform, "dj4100") || (!strcmp(m_pJA->printer_platform, "dj2600")))
574     { 
575         //Encapsulator for Viper Trim class products is not written properly, hence mapping the Index to
576         //old values.   
577         iPMIndex = PQ_Cartridge_Map_ViperTrim[m_pJA->integer_values[2]][m_pJA->integer_values[1]];      
578     }
579     else
580     {
581         iPMIndex = PQ_Cartridge_Map[m_pJA->integer_values[2]][m_pJA->integer_values[1]];
582                                                                         //m_pJA->integer_values[1] is basically cupsInteger1 value given in PPD.
583                                                                         //m_pJA->integer_values[2] is basically cupsInteger2 value given in PPD.    
584     }
585
586     dbglog("CupeInteger1 = [%d]\n",m_pJA->integer_values[1]); 
587     dbglog("CupeInteger2 = [%d]\n",m_pJA->integer_values[2]); 
588     dbglog("PrintMode Index = [%d]\n",iPMIndex); 
589     
590     if( -1 == iPMIndex)
591     {
592         dbglog("Unsupported Cartridge and Print Quality combination..\n");
593         return false;
594     }
595             
596     for (int i = 0; i < lidil_print_modes_table[index].count; i++, p++)
597     {
598         if (i == iPMIndex)
599         {
600             dbglog("Print Mode = [%s]\n",p->name); 
601             m_pPM = p;
602             return true;
603         }
604     }
605     return false;
606 }
607
608 /*
609 bool Lidil::selectPrintMode(int index)
610 {
611     PrintMode    *p = lidil_print_modes_table[index].print_modes;    
612     for (int i = 0; i < lidil_print_modes_table[index].count; i++, p++)
613     {
614         if (!strcmp(m_pJA->quality_attributes.print_mode_name, p->name))
615         {        
616             m_pPM = p;
617             return true;
618         }
619     }
620     return false;
621 }*/
622
623
624 bool Lidil::selectPrintMode()
625 {
626     if (m_pJA->printer_platform[0] == 0)
627     {
628         dbglog("printer_platform is undefined");
629         return false;
630     }
631     for (unsigned int i = 0; i < sizeof(lidil_print_modes_table) / sizeof(lidil_print_modes_table[0]); i++)
632     {
633         if (!strcmp(m_pJA->printer_platform, lidil_print_modes_table[i].printer_platform_name))
634         {
635             return selectPrintMode(i);
636         }
637     }
638     dbglog("Unsupported printer_platform: %s", m_pJA->printer_platform);
639     return false;
640 }
641
642 DRIVER_ERROR Lidil::loadSweepData (BYTE *imagedata, int imagesize)
643 {
644     UInt16 mem_needed = SIZEOF_LDLHDR + SIZEOF_LDL_LDSWPDATA_CMDOPT
645                                       + SIZEOF_LDLTERM;
646     cur_pcl_buffer_ptr = pcl_buffer;
647     memset (pcl_buffer, 0, mem_needed);
648     if (mem_needed < LDLPACKET_MINSIZE)
649     {
650         memset(pcl_buffer + mem_needed-1, 0xFF, LDLPACKET_MINSIZE - mem_needed);
651     mem_needed = LDLPACKET_MINSIZE;
652     }
653
654     BYTE    *compressed_dataptr = imagedata;
655     UInt16  compressed_size     = imagesize;
656
657     if (m_pLidilCompress)
658     {
659         m_pLidilCompress->Init ((UInt16 *) (imagedata+16), imagesize);
660         m_pLidilCompress->CompressData ();
661         m_pLidilCompress->GetFrameInfo (&compressed_dataptr, &compressed_size);
662     }
663
664     fillLidilHeader (NULL, eLDLLoadSweepData, mem_needed, compressed_size);
665     addInt16 (imagesize);
666     pcl_buffer[15] = FRAME_SYN;
667
668     memcpy (compressed_dataptr, pcl_buffer, 16);
669     cur_pcl_buffer_ptr = pcl_buffer;
670     return (sendBuffer ((const BYTE *) compressed_dataptr, compressed_size+16));
671 }
672
673 DRIVER_ERROR Lidil::printSweep (UInt32 SweepSize,
674                                 bool ColorPresent,
675                                 bool BlackPresent,
676                     bool PhotoPresent,
677                                 Int32 VerticalPosition,
678                                 Int32 LeftEdge,
679                                 Int32 RightEdge,
680                                 char PrintDirection,
681                                 Int16 sFirstNozzle,
682                                 Int16 sLastNozzle)
683 {
684     DRIVER_ERROR    err;
685     // determine how many colors will be generated
686     UInt16 colorcount = 0;
687     UInt32  uiAffectedColors = 0;
688     if (ColorPresent == true) colorcount += 3;
689     if (BlackPresent == true) colorcount++;
690     if (PhotoPresent == true) 
691     {
692         if (ColorPresent == false)
693             colorcount++;
694         else
695             colorcount+=3;
696     }
697
698     UInt16  mem_needed;
699     if (m_lidil_version == 1)
700     {
701         mem_needed =   SIZEOF_LDLHDR
702                          + SIZEOF_LDL_PRTSWP_CMDOPT
703                          + SIZEOF_LDL_PRTSWP_OPTFLDS
704                          + SIZEOF_LDL_PRTSWP_COLROPT * colorcount
705                          + SIZEOF_LDLTERM;
706     
707         if (colorcount != 0)
708             mem_needed += SIZEOF_LDL_COLROPT_ACTIVECOLR;
709     }
710     else
711     {
712         mem_needed =   SIZEOF_LDLHDR
713                          + SIZEOF_LDL_PRTSWP_CMDOPT + 7
714                          + SIZEOF_LDL_PRTSWP_OPTFLDS
715                          + SIZEOF_LDL_PRTSWP_COLROPT + 4
716                          + SIZEOF_LDLTERM;
717     }
718
719     memset (pcl_buffer, 0, mem_needed);
720     cur_pcl_buffer_ptr = pcl_buffer;
721
722     fillLidilHeader (NULL, eLDLPrintSweep, mem_needed);
723     if (m_lidil_version == 2)
724     {
725         *cur_pcl_buffer_ptr++ = 1;    // Version number
726     }
727     addInt32 (SweepSize);
728     addInt32 (VerticalPosition);
729     addInt32 (m_iLeftMargin);
730     if (m_lidil_version == 1)
731     {
732         // LIDIL First Version
733         *cur_pcl_buffer_ptr++ = SWINGFMT_UNCOMPRSS;
734     }
735     else
736     {
737         // LIDIL Second Version
738         *cur_pcl_buffer_ptr++ = 1;
739     }
740     *cur_pcl_buffer_ptr++ = PrintDirection;
741     if (m_lidil_version == 2)
742     {
743         addInt32 (0); // Shingle mask
744     }
745     addInt32 (IPS_CARRSPEED|IPS_INIPRNSPEED|ACCURATEPOSN_NEEDED);
746  // Carriage Speed - 25 for plain, 12 for photo
747     if (m_pQA->print_quality == BEST_QUALITY && m_pQA->media_type == MEDIATYPE_PHOTO)
748         *cur_pcl_buffer_ptr++ = 12;
749     else
750         *cur_pcl_buffer_ptr++ = 25;
751     *cur_pcl_buffer_ptr++ = 4; // Initial Print Speed
752     *cur_pcl_buffer_ptr++ = 1; // Need Accurate Position
753     if (m_lidil_version == 2)
754     {
755         *cur_pcl_buffer_ptr++ = 1; // Number of entries in the sweep
756     }
757
758     // fill in the color information
759     if (colorcount == 0)
760     {
761         *cur_pcl_buffer_ptr++ = NO_ACTIVE_COLORS;
762         *cur_pcl_buffer_ptr++ = FRAME_SYN;
763         // write out the data
764         err = Cleanup();
765         return err;
766     }
767
768     // figure out what are the active colors and fill in the optional color fields.
769
770     UInt16 colrpresent = 0;
771     UInt16 colr_found=0;
772     UInt16 colormask = 0x01;
773     UInt16 offset = eLDLBlack;
774     UInt16 iDataRes;
775     UInt16 iPrintRes;
776     uiAffectedColors = offset;
777     if (BlackPresent == true)
778     {
779     uiAffectedColors = 0x1;
780     }
781     if(BlackPresent == false && PhotoPresent == false)
782     {
783     offset = eLDLCyan;
784     colormask=0x02;
785     uiAffectedColors |= 0x0000000e;
786     }
787     else if (BlackPresent == false && PhotoPresent == true)
788     {
789         if (ColorPresent == true)
790         {
791             offset = eLDLCyan;
792             colormask=0x02;
793             uiAffectedColors |= 0x0000007e;
794         }
795         else
796         {
797             offset = eLDLLoBlack;
798             colormask=0x40;
799             uiAffectedColors |= 0x00000070;
800         }
801     }
802
803     int actv_colr_index = cur_pcl_buffer_ptr - pcl_buffer;
804     int iColorRes = 300;
805     if (m_lidil_version == 1)
806     {
807         cur_pcl_buffer_ptr += 2;
808     }
809     else
810     {
811         iColorRes = 600;
812     }
813     for(UInt16 i = offset; colr_found < colorcount && i < eLDLMaxColor; i++)
814     {
815         colr_found++;
816         colrpresent = colrpresent | colormask;
817
818         if (m_lidil_version == 2)
819         {
820             addInt32 (uiAffectedColors);
821         }
822         addInt32 (LeftEdge);
823         addInt32 (RightEdge);
824         addInt32 (LeftEdge);
825         addInt32 (RightEdge);
826
827         if ((i == 0 && m_lidil_version == 1) || (BlackPresent && m_lidil_version == 2))
828         {
829             iDataRes = 600;
830             iPrintRes = m_iBlackPenResolution;
831         }
832         else
833         {
834             iDataRes  = iColorRes; // 300;
835             iPrintRes = iColorRes; // 300;
836         }
837         addInt16 (iDataRes);         // Vertical Data Resolution
838         addInt16 (iPrintRes);        // Vertical Print Resolution
839
840         if (m_lidil_version == 2)
841         {
842             addInt16 (m_pQA->horizontal_resolution * m_iBitDepth);   // Horizontal Data Resolution // Collie
843         }
844         else
845         {
846             addInt16 (m_pQA->horizontal_resolution);
847         }
848
849         if (m_pQA->horizontal_resolution == 300)
850         {
851             addInt16 (600);   // Force 2 drop for draft mode.
852         }
853         else
854         {
855             if (m_lidil_version == 2)
856             {
857                 addInt16 (m_pQA->horizontal_resolution * m_iBitDepth);   // Horizontal Print Resolution // Collie
858             }
859             else
860             {
861             addInt16 (m_pQA->horizontal_resolution);
862             }
863         }
864         addInt16 (sFirstNozzle);
865         if (sLastNozzle == 0)
866         {
867             int     iTmp = m_iRasterCount / m_pPM->dyeCount;;
868             if (m_lidil_version == 2)
869             {
870                 addInt16 (sFirstNozzle - 1 + ((iTmp * iPrintRes) / (m_pQA->vertical_resolution * m_iBitDepth))); // Collie
871             }
872             else
873             {
874                 addInt16 (sFirstNozzle - 1 + ((iTmp * iPrintRes) / (m_pQA->vertical_resolution)));
875             }
876         }
877         else
878         {
879             addInt16 (sLastNozzle);
880         }
881
882         *cur_pcl_buffer_ptr++ = 0;    // Vertical Alignment
883         colormask = colormask << 1;
884         if (m_lidil_version == 2)
885         {
886             break;
887         }
888     }
889     // write the active color field
890     if (m_lidil_version == 1)
891     {
892         BYTE    *tmp = cur_pcl_buffer_ptr;
893         cur_pcl_buffer_ptr = pcl_buffer + actv_colr_index;
894         addInt16 (colrpresent);
895         cur_pcl_buffer_ptr = tmp;
896     }
897
898     if (m_lidil_version == 2)
899     {
900         *cur_pcl_buffer_ptr++ = 0; // # of entries in the shingle array
901     }
902     *cur_pcl_buffer_ptr++ = FRAME_SYN;
903
904     // write out the data
905     err = Cleanup();
906     return err;
907 }
908
909 DRIVER_ERROR Lidil::allocateSwathBuffers()
910 {
911     int size = m_pMA->printable_width;
912     size = (size + 7) / 8;
913     m_iImageWidth = size;
914     m_ldlCompressData = NULL;
915     if (m_lidil_version == 1)
916     {
917 //        m_ldlCompressData = new comp_ptrs_t;
918     }
919
920     if (m_iBitDepth == 2)
921     {
922         size *= 2;
923     }
924
925     int     iCompressBufSize = (m_iBytesPerSwing / 2) * LDL_MAX_IMAGE_SIZE+20;    // additional space for load sweep command
926     m_szCompressBuf = new BYTE[iCompressBufSize];
927     if (m_szCompressBuf == NULL)
928         return ALLOCMEM_ERROR;
929     memset (m_szCompressBuf, 0, iCompressBufSize);
930
931     BYTE    *p = NULL;
932     int     iSwathBuffSize;
933
934     m_sSwathHeight = SWATH_HEIGHT;
935
936 /*
937  *  This swath buffer cannot be greater than the number of nozzles - 400 for black
938  *  and 100 for color - we can use.
939  */
940
941     int    iAdjHeight = (m_iNumBlackNozzles / 32) * 8;
942     if (m_pPM->dyeCount == 1)
943     {
944         m_sSwathHeight = m_sSwathHeight * 4;
945         if ((int) (m_sSwathHeight * 1200 / m_pQA->vertical_resolution) > m_iNumBlackNozzles)
946             m_sSwathHeight = m_pQA->vertical_resolution / 3;
947     }
948     else if (m_pQA->print_quality != DRAFT_QUALITY && m_pQA->vertical_resolution > 300 && m_pPM->dyeCount > 1 && m_iBitDepth == 1) // Collie change
949     {
950         m_sSwathHeight = (m_sSwathHeight / 4) * 4 * 2;
951         if (m_sSwathHeight > 200)
952             m_sSwathHeight = 200;
953     }
954     else if (m_iBitDepth == 2)
955         m_sSwathHeight = iAdjHeight * 4;
956
957     if (m_pQA->print_quality == NORMAL_QUALITY)
958         m_sSwathHeight = iAdjHeight * 2;
959
960     if (m_pQA->print_quality == DRAFT_QUALITY && m_pPM->dyeCount != 1)
961     {
962         m_sSwathHeight *= m_iBytesPerSwing / 2;
963     }
964
965     iSwathBuffSize = m_pPM->dyeCount * sizeof (BYTE *) +
966                      m_pPM->dyeCount * m_sSwathHeight * sizeof (BYTE *) +
967                      size * m_pPM->dyeCount * m_sSwathHeight;
968     if ((p = new BYTE[iSwathBuffSize]) == NULL)
969     {
970         return ALLOCMEM_ERROR;
971     }
972
973     int     i;
974     m_SwathData = (BYTE ***) p;
975     for (i = 0; i < (int) m_pPM->dyeCount; i++)
976         m_SwathData[i] = (BYTE **) (p + sizeof (BYTE *) * m_pPM->dyeCount + i * m_sSwathHeight * sizeof (BYTE *));
977
978     for (i = 0; i < (int) m_pPM->dyeCount; i++)
979     {
980         p = (BYTE *) m_SwathData + sizeof (BYTE *) * m_pPM->dyeCount +
981                 m_pPM->dyeCount * m_sSwathHeight * sizeof (BYTE *) +
982                 size * m_sSwathHeight * i;
983         for (int j = 0; j < m_sSwathHeight; j++)
984         {
985             memset (p, 0, size);
986             m_SwathData[i][j] = p;
987             p = p + size;
988         }
989     }
990
991     if (m_pQA->print_quality != DRAFT_QUALITY && m_pQA->vertical_resolution != 300)
992     {
993         m_iRasterCount = (m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * m_pPM->dyeCount;
994         m_iVertPosn -= (((m_sSwathHeight - m_sSwathHeight / (4*m_iBitDepth)) * 600 / m_pQA->vertical_resolution) * DEVUNITS_XBOW / 600);
995     }
996     m_cPassNumber = 0;
997
998     if (m_pJA->print_borderless)
999     {
1000         if (m_iVertPosn < -850) m_iVertPosn = -850;
1001     }
1002     else
1003     {
1004         if (m_iVertPosn < -600) m_iVertPosn = -600;
1005     }
1006     if (m_iBitDepth == 2)
1007         m_iVertPosn += 6;
1008     return NO_ERROR;
1009 }
1010
1011 unsigned int Lidil::getSwathWidth (int iStart, int iLast, int iWidth)
1012 {
1013     int k;
1014     int i, j;
1015     for (i = iWidth - 1; i > -1; i--)
1016     {
1017         for (j = iStart; j < iLast; j++)
1018         {
1019             for (k = m_iRasterCount / m_pPM->dyeCount-1; k >= 0; k--)
1020             {
1021
1022                 if (m_SwathData[j][k][i])
1023                 {
1024                     return (i+1);
1025                 }
1026             }
1027         }
1028     }
1029
1030     return 0;
1031 }
1032
1033 DRIVER_ERROR Lidil::processSwath()
1034 {
1035     DRIVER_ERROR    err = NO_ERROR;
1036     Int16           sCurSwathHeight = m_iRasterCount / m_pPM->dyeCount;
1037     m_iVertPosn += ((m_iBlankRasters) * 600 / m_pQA->vertical_resolution) * DEVUNITS_XBOW / 600;
1038     m_iBlankRasters = 0;
1039
1040     bool    bColorPresent = true;
1041     bool    bBlackPresent = true;
1042     bool    bPhotoPresent = true;
1043     short   sColorSize = 0;
1044     int     LeftEdge = 0;
1045     BYTE    csavMask;
1046
1047     if (m_pPM->dyeCount == 1)
1048     {
1049         bColorPresent = false;
1050         bPhotoPresent = false;
1051     }
1052     if (m_pPM->dyeCount == 3)
1053     {
1054         bBlackPresent = false;
1055         bPhotoPresent = false;
1056     }
1057     if (m_pPM->dyeCount == 6)
1058     {
1059         bBlackPresent = false;
1060     }
1061     if (m_pPM->dyeCount == 4)
1062     {
1063         bPhotoPresent = false;
1064     }
1065
1066     if (!m_bBidirectionalPrintingOn)
1067         m_cPrintDirection = PRNDRN_LEFTTORIGHT;
1068
1069     int     iStartRaster = m_cPassNumber % (2 * m_iBitDepth);
1070     BYTE    mask = 0xFF;
1071
1072     if (m_lidil_version == 2)
1073     {
1074         iStartRaster = 0;   // Version 2 - REVISIT
1075     }
1076
1077     if (m_pQA->print_quality != DRAFT_QUALITY && m_pQA->vertical_resolution != 300)
1078     {
1079         if ((m_cPassNumber % (4 * m_iBitDepth)) < (2 * m_iBitDepth))
1080             mask = 0xAA;
1081         else
1082             mask = 0x55;
1083     }
1084     csavMask = mask;
1085
1086 /*
1087  *  Check if RefCount is close to overflow of 65k.
1088  */
1089
1090     if (m_sRefCount > 64000)
1091         m_sRefCount = 6;
1092
1093 /*
1094  *  Photo Swath
1095  */
1096
1097     err = processPhotoSwath(bPhotoPresent, bColorPresent, mask);
1098     if (err != NO_ERROR)
1099         return err;
1100
1101 /*
1102  *  Color Swath
1103  */
1104
1105     err = processColorSwath(bPhotoPresent, bColorPresent, bBlackPresent, &sColorSize,  mask);
1106     if (err != NO_ERROR)
1107         return err;
1108 /*
1109  *  Black Swath
1110  */
1111
1112     err = processBlackSwath(bBlackPresent, bColorPresent, sColorSize, LeftEdge, csavMask);
1113
1114     m_iRasterCount = 0;
1115
1116     if (m_pQA->print_quality != DRAFT_QUALITY && m_pQA->vertical_resolution != 300)
1117     {
1118         m_cPassNumber = (m_cPassNumber + 1) % (4 * m_iBitDepth);
1119         m_iVertPosn += ((((sCurSwathHeight/(4 * m_iBitDepth))) * 600 / m_pQA->vertical_resolution) * DEVUNITS_XBOW / 600) / m_iBitDepth;
1120         if (m_iBitDepth == 1)
1121         {
1122             if (m_cPassNumber % 2)
1123                 m_iVertPosn += 4;
1124             else
1125                 m_iVertPosn -= 4;
1126         }
1127         else
1128         {
1129             m_iVertPosn -= 2;
1130             if ((m_cPassNumber % 4) == 0)
1131                   m_iVertPosn += (DEVUNITS_XBOW / m_iColorPenResolution);
1132         }
1133         m_iRasterCount = (sCurSwathHeight - sCurSwathHeight / (4 * m_iBitDepth)) * m_pPM->dyeCount;
1134     }
1135     else
1136     {
1137         m_iVertPosn += ((sCurSwathHeight * 4 * 600) / m_pQA->vertical_resolution);
1138
1139     }
1140
1141     return err;
1142 }
1143
1144 DRIVER_ERROR Lidil::processPhotoSwath(bool    bPhotoPresent,
1145                                       bool    bColorPresent,
1146                                       BYTE    mask)
1147 {
1148     if (!bPhotoPresent)
1149     {
1150         return NO_ERROR;
1151     }
1152
1153     BYTE            csavMask = mask;
1154     int             iOffset = 0;
1155     int             i;
1156     int             j;
1157     int             n;
1158     int             count;
1159     int             size;
1160     int             start;
1161     DRIVER_ERROR    err = NO_ERROR;
1162     int             sCurSwathHeight = m_iRasterCount / m_pPM->dyeCount;
1163     unsigned int    uiSwathSize;
1164     int             LeftEdge = 0;
1165     int             RightEdge;
1166     int             iStartRaster = 0;
1167     int             delta;
1168     int    iColors    = 1;
1169     int    LastColor  = 1;
1170     int    StartColor = 0;
1171     int    width = m_iImageWidth;
1172     if (bColorPresent)
1173     {
1174         iColors = 6;
1175         LastColor = 6;
1176         StartColor = 0;
1177         if (m_lidil_version != 1)
1178         {
1179             width *= m_iBitDepth;
1180         }
1181     }
1182     size = getSwathWidth (StartColor, LastColor, width);
1183     if (size == 0)
1184         return NO_ERROR;
1185
1186     if (size % m_iBytesPerSwing)
1187         size = ((size/m_iBytesPerSwing) + 1) * m_iBytesPerSwing;
1188     if (m_lidil_version == 1)
1189     {
1190         RightEdge = LeftEdge + (size * 8 * 600 / m_pQA->horizontal_resolution - 1 * (600 / m_pQA->vertical_resolution)) *
1191                                 (DEVUNITS_XBOW / 600);
1192     }
1193     else
1194     {
1195         RightEdge = LeftEdge + (size * 8 * 600 / m_pQA->horizontal_resolution - 1 * (600 / m_pQA->vertical_resolution)) *
1196                                 (DEVUNITS_XBOW / (600 * m_iBitDepth));
1197     }
1198     Int16   sLastNozzle;
1199     Int16   sFirstNozzle = 1;
1200     unsigned int    uSweepSize;
1201     int     jDelta = m_pQA->vertical_resolution / m_iColorPenResolution;
1202     jDelta *= m_iBitDepth;
1203
1204     uiSwathSize = size * iColors * sCurSwathHeight / jDelta;
1205
1206     uSweepSize = sCurSwathHeight * m_iBytesPerSwing / jDelta;
1207     n = LDL_MAX_IMAGE_SIZE / (uSweepSize);
1208     count = 0;
1209
1210     if (m_iBitDepth == 2)
1211         iStartRaster = (4 - (iStartRaster+1)) % 4;
1212
1213     if (m_lidil_version == 2)
1214     {
1215         iStartRaster = 0;   // Collie - REVISIT
1216     }
1217
1218     sLastNozzle = sFirstNozzle - 1 + sCurSwathHeight / jDelta;
1219
1220     BYTE *cb = m_szCompressBuf + 16;    // load sweep command
1221     memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1222
1223     // 1200 dpi split into two
1224     int    ib = 0;
1225
1226     if (m_pQA->vertical_resolution > 300 && m_pQA->print_quality != DRAFT_QUALITY)
1227     {
1228         iOffset = (sCurSwathHeight / (4 * m_iBitDepth));
1229         iOffset = iOffset + iOffset * ((m_cPassNumber) % (4 * m_iBitDepth));
1230     }
1231
1232     BYTE    cVertAlign = 0;
1233
1234     if (bColorPresent)
1235     {
1236         cVertAlign = m_cPtoCVertAlign;
1237     }
1238
1239     for (ib = 0; ib < (int) m_iBitDepth; ib++)
1240     {
1241         if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
1242         {
1243             start = size - m_iBytesPerSwing;
1244             delta = -m_iBytesPerSwing;
1245         }
1246         else
1247         {
1248             start = 0;
1249             delta = m_iBytesPerSwing;
1250         }
1251
1252         err = printSweep (uiSwathSize, bColorPresent, false, bPhotoPresent,
1253                                   m_iVertPosn+cVertAlign, LeftEdge, RightEdge, m_cPrintDirection,
1254                                   sFirstNozzle, sLastNozzle);
1255                 ERRCHECK;
1256
1257         i = start + ib * m_iImageWidth;     // 1200 dpi split into two
1258         for (int l = 0; l < size; l += m_iBytesPerSwing)   // Collie
1259         {
1260             for (int k = StartColor+1; k < LastColor; k++)
1261             {
1262                 mask = csavMask;
1263                 for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
1264                 {
1265                     for (int is = 0; is < m_iBytesPerSwing; is++)
1266                     {
1267                         *cb++ = m_SwathData[k][j][i+is]   & mask;
1268                     }
1269                     mask = ~mask;
1270                 }
1271                 for (j = iStartRaster; j < iOffset; j += jDelta)
1272                 {
1273                     for (int is = 0; is < m_iBytesPerSwing; is++)
1274                     {
1275                         *cb++ = m_SwathData[k][j][i+is]   & mask;
1276                     }
1277                     mask = ~mask;
1278                 }
1279
1280                 count++;
1281                 if (count == n)
1282                 {
1283                     err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1284                     memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1285                     cb = m_szCompressBuf+16;
1286                     count = 0;
1287                     ERRCHECK;
1288                 }
1289             }
1290             mask = csavMask;
1291             for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
1292             {
1293                 for (int is = 0; is < m_iBytesPerSwing; is++)
1294                 {
1295                     *cb++ = m_SwathData[0][j][i + is]   & mask;
1296                 }
1297                 mask = ~mask;
1298             }
1299             for (j = iStartRaster; j < iOffset; j += jDelta)
1300             {
1301                 for (int is = 0; is < m_iBytesPerSwing; is++)
1302                 {
1303                     *cb++ = m_SwathData[0][j][i + is]   & mask;
1304                 }
1305                 mask = ~mask;
1306             }
1307
1308             count++;
1309             if (count == n)
1310             {
1311                 err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1312                 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1313                 cb = m_szCompressBuf+16;
1314                 count = 0;
1315                 ERRCHECK;
1316             }
1317             i = i + delta;
1318         }
1319         if (count != 0)
1320         {
1321             err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1322             memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1323             cb = m_szCompressBuf+16;
1324             count = 0;
1325             ERRCHECK;
1326         }
1327
1328         if (m_bBidirectionalPrintingOn)
1329             m_cPrintDirection = (m_cPrintDirection + 1) % 2;
1330
1331         if (m_lidil_version == 2) // Collie
1332         {
1333             break;
1334         }
1335         LeftEdge += 2;
1336         RightEdge += 2;
1337
1338     }   // 1200 dpi split into two - end of for ib = 0 loop
1339     return err;
1340 }
1341
1342 DRIVER_ERROR Lidil::processColorSwath(bool    bPhotoPresent,
1343                                       bool    bColorPresent,
1344                                       bool    bBlackPresent,
1345                       short   *sColorSize,
1346                                       BYTE    mask)
1347 {
1348     BYTE            csavMask = mask;
1349     int             iStartRaster = 0;
1350     int             LeftEdge = 0;
1351     int             RightEdge;
1352     unsigned int    start;
1353     int             size;
1354     unsigned int    delta;
1355     int             i;
1356     int             j;
1357     int             n;
1358     int             count;
1359     int             iOffset = 0;
1360     DRIVER_ERROR    err = NO_ERROR;
1361     int             sCurSwathHeight = m_iRasterCount / m_pPM->dyeCount;
1362     unsigned int    uiSwathSize;
1363     if (bPhotoPresent || !bColorPresent)
1364     {
1365         return NO_ERROR;
1366     }
1367
1368     int    iColors = 3;
1369     int    LastColor = 4;
1370     int    StartColor = 1;
1371     if (!bBlackPresent)
1372     {
1373         StartColor = 0;
1374         LastColor  = 3;
1375     }
1376     if (m_lidil_version == 1)
1377     {
1378         // 1200 dpi split into two
1379         size = getSwathWidth (StartColor, LastColor, m_iImageWidth/* * m_iBitDepth*/);
1380     }
1381     else
1382     {
1383         size = getSwathWidth (StartColor, LastColor, m_iImageWidth * m_iBitDepth);
1384     }
1385     *sColorSize = size;
1386     if (size == 0)
1387     {
1388         return NO_ERROR;
1389     }
1390
1391     if (size % m_iBytesPerSwing)
1392     size = ((size / m_iBytesPerSwing) + 1) * m_iBytesPerSwing;
1393
1394     if (m_lidil_version == 1)
1395     {
1396     RightEdge = LeftEdge + (size * 8 * 600 / m_pQA->horizontal_resolution - 1 * (600 / m_pQA->vertical_resolution)) *
1397                 (DEVUNITS_XBOW / 600);
1398     }
1399     else
1400     {
1401     RightEdge = LeftEdge + (size * 8 * 600 / m_pQA->horizontal_resolution - 1 * (600 / m_pQA->vertical_resolution)) *
1402                 (DEVUNITS_XBOW / (600 * m_iBitDepth));
1403     }
1404     Int16   sLastNozzle;
1405     Int16   sFirstNozzle = 1;
1406     unsigned int    uSweepSize;
1407     int     jDelta = m_pQA->vertical_resolution / m_iColorPenResolution;
1408     jDelta *= m_iBitDepth;
1409
1410     uiSwathSize = size * iColors * sCurSwathHeight / jDelta;
1411
1412     uSweepSize = sCurSwathHeight * m_iBytesPerSwing / jDelta;
1413     n = LDL_MAX_IMAGE_SIZE / (uSweepSize);
1414     count = 0;
1415
1416     if (m_iBitDepth == 2)
1417     {
1418     iStartRaster = (4 - (iStartRaster+1)) % 4;
1419     if (m_lidil_version == 2)
1420     {
1421         iStartRaster = m_cPassNumber % (m_iBitDepth);
1422     }
1423     }
1424
1425     sLastNozzle = sFirstNozzle - 1 + sCurSwathHeight / jDelta;
1426
1427     BYTE *cb = m_szCompressBuf + 16;    // load sweep command
1428     memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1429
1430     // 1200 dpi split into two
1431     int    ib = 0;
1432
1433     if (m_pQA->vertical_resolution > 300 && m_pQA->print_quality != DRAFT_QUALITY)
1434     {
1435     iOffset = (sCurSwathHeight / (4 * m_iBitDepth));
1436     iOffset = iOffset + iOffset * ((m_cPassNumber) % (4 * m_iBitDepth));
1437     }
1438
1439     for (ib = 0; ib < (int) m_iBitDepth; ib++)
1440     {
1441     if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
1442     {
1443         start = size - m_iBytesPerSwing;
1444         delta = -m_iBytesPerSwing;
1445     }
1446     else
1447     {
1448         start = 0;
1449         delta = m_iBytesPerSwing;
1450     }
1451     err = printSweep (uiSwathSize, bColorPresent, false, false,
1452               m_iVertPosn, LeftEdge, RightEdge, m_cPrintDirection,
1453               sFirstNozzle, sLastNozzle);
1454     ERRCHECK;
1455
1456     i = start + ib * m_iImageWidth;     // 1200 dpi split into two
1457     for (int l = 0; l < size; l += m_iBytesPerSwing)   // Collie
1458     {
1459         for (int k = StartColor; k < LastColor; k++)
1460         {
1461         mask = csavMask;
1462         for (j = iOffset + iStartRaster; j < sCurSwathHeight; j += jDelta)
1463         {
1464             for (int is = 0; is < m_iBytesPerSwing; is++)
1465             {
1466             *cb++ = m_SwathData[k][j][i + is]   & mask;
1467             }
1468             mask = ~mask;
1469         }
1470         for (j = iStartRaster; j < iOffset; j += jDelta)
1471         {
1472             for (int is = 0; is < m_iBytesPerSwing; is++)
1473             {
1474             *cb++ = m_SwathData[k][j][i + is]   & mask;
1475             }
1476             mask = ~mask;
1477         }
1478
1479         count++;
1480         if (count == n)
1481         {
1482             err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1483             memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1484
1485             cb = m_szCompressBuf+16;
1486             count = 0;
1487             ERRCHECK;
1488         }
1489
1490         }
1491         i = i + delta;
1492
1493     }
1494     if (count != 0)
1495     {
1496         err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1497         memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1498
1499         cb = m_szCompressBuf+16;
1500         count = 0;
1501         ERRCHECK;
1502     }
1503
1504     LeftEdge += 2;
1505     RightEdge += 2;
1506
1507     if (m_bBidirectionalPrintingOn)
1508         m_cPrintDirection = (m_cPrintDirection + 1) % 2;
1509     if (m_lidil_version == 2) // Collie
1510     {
1511         break;
1512     }
1513
1514     }   // 1200 dpi split into two - end of for ib = 0 loop
1515     return err;
1516 }
1517
1518 DRIVER_ERROR Lidil::processBlackSwath(bool     bBlackPresent,
1519                                       bool     bColorPresent,
1520                                       short    sColorSize,
1521                                       int      LeftEdge,
1522                                       BYTE     mask)
1523 {
1524     Int32           RightEdge;
1525     unsigned int    start;
1526     unsigned int    delta;
1527     int             i;
1528     int             j;
1529     int             n;
1530     int             count;
1531     int             iOffset = 0;
1532     DRIVER_ERROR    err = NO_ERROR;
1533     int             sCurSwathHeight = m_iRasterCount / m_pPM->dyeCount;
1534     unsigned int    uiSwathSize;
1535
1536     if (!bBlackPresent)
1537     {
1538         return NO_ERROR;
1539     }
1540     int size = getSwathWidth (0, 1, m_iImageWidth);
1541     if (size == 0)
1542         return NO_ERROR;
1543
1544     if (size % m_iBytesPerSwing)
1545 size = ((size/m_iBytesPerSwing) + 1) * m_iBytesPerSwing;
1546
1547     RightEdge = LeftEdge + (size * 8 * 600 / m_pQA->horizontal_resolution - 1 * (600 / m_pQA->vertical_resolution)) * DEVUNITS_XBOW/600;
1548     if (m_iBitDepth != 2 && ((m_cPassNumber % 2) == 0 || m_pQA->print_quality == DRAFT_QUALITY))
1549     {
1550         Int16   sLastNozzle = 0;
1551         Int16   sFirstNozzle = 1;
1552
1553         int     xDelta = 0;
1554         BYTE    cVertAlign = 0;
1555
1556         if (bColorPresent)
1557         {
1558             cVertAlign = m_cKtoCVertAlign;
1559         }
1560
1561         if (bColorPresent && sColorSize && m_bBidirectionalPrintingOn)
1562             m_cPrintDirection = PRNDRN_RIGHTTOLEFT;
1563         if (m_cPrintDirection == PRNDRN_RIGHTTOLEFT)
1564         {
1565             start = size - m_iBytesPerSwing;
1566             delta = -m_iBytesPerSwing;
1567         }
1568         else
1569         {
1570             start = 0;
1571             delta = m_iBytesPerSwing;
1572         }
1573         if (m_pQA->vertical_resolution == 300)
1574             xDelta = m_iBytesPerSwing;
1575         uiSwathSize = ((size/m_iBytesPerSwing) * sCurSwathHeight * m_iBytesPerSwing * (600 * m_iBitDepth)/ m_pQA->vertical_resolution);
1576
1577         if (m_lidil_version == 2 && m_pPM->dyeCount != 1)
1578         {
1579             sFirstNozzle = 9;
1580         }
1581
1582         err = printSweep (uiSwathSize, false, bBlackPresent, false,
1583             (m_iVertPosn + cVertAlign), LeftEdge, RightEdge, m_cPrintDirection, sFirstNozzle, sLastNozzle);
1584         ERRCHECK;
1585
1586         i = start;
1587         BYTE *cb = m_szCompressBuf+16;
1588         memset (m_szCompressBuf, 0x0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1589
1590         n = LDL_MAX_IMAGE_SIZE / (sCurSwathHeight * m_iBytesPerSwing * 600 / m_pQA->vertical_resolution);
1591         count = 0;
1592         iOffset = 0;
1593         if (m_pQA->vertical_resolution > 300 && m_pQA->print_quality != DRAFT_QUALITY)
1594         {
1595             iOffset = sCurSwathHeight / 4;
1596             iOffset = iOffset + iOffset * (m_cPassNumber % 4);
1597         }
1598
1599         for (int l = 0; l < size; l += m_iBytesPerSwing) // Collie
1600         {
1601             for (j = iOffset; j < sCurSwathHeight; j++)
1602             {
1603                 for (int is = 0; is < m_iBytesPerSwing; is++)
1604                 {
1605                     *cb++ = m_SwathData[0][j][i + is]   & mask;
1606                 }
1607                 cb += xDelta;
1608             }
1609             for (j = 0; j < iOffset; j++)
1610             {
1611                 for (int is = 0; is < m_iBytesPerSwing; is++)
1612                 {
1613                     *cb++ = m_SwathData[0][j][i + is]   & mask;
1614                 }
1615                 cb += xDelta;
1616             }
1617
1618             count++;
1619             if (count == n)
1620             {
1621                 err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1622                 memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1623
1624                 cb = m_szCompressBuf+16;
1625                 count = 0;
1626                 ERRCHECK;
1627             }
1628             i = i + delta;
1629         }
1630         if (count != 0)
1631         {
1632             err = loadSweepData (m_szCompressBuf, (unsigned int) (cb - m_szCompressBuf-16));
1633             memset (m_szCompressBuf, 0, LDL_MAX_IMAGE_SIZE * (m_iBytesPerSwing / 2));
1634
1635             cb = m_szCompressBuf+16;
1636             count = 0;
1637             ERRCHECK;
1638         }
1639
1640         if (m_bBidirectionalPrintingOn)
1641             m_cPrintDirection = (m_cPrintDirection + 1) % 2;
1642     }
1643     return err;
1644 }
1645
1646 bool Lidil::isBlankRaster(BYTE *raster, int width)
1647 {
1648     if (*raster == 0 && !memcmp(raster+1, raster, width-1))
1649         return true;
1650     return false;
1651 }
1652
1653 void Lidil::applyShingleMask(int iCPlane, BYTE *input)
1654 {
1655     // do the dotmapping here
1656     BYTE    cbyte1, cbyte2;
1657     BYTE    c1, c2;
1658     int     j = 0;
1659     BYTE    r1b1 = 0;
1660     BYTE    r1b2 = 0;
1661     BYTE    r2b1 = 0;
1662     BYTE    r2b2 = 0;
1663     BYTE    bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
1664
1665     // Collie changes
1666     int     iNextBitPos = m_iImageWidth;
1667     int     iJIncrement = 1;
1668     if (m_lidil_version == 2)
1669     {
1670         iNextBitPos = 1;
1671         iJIncrement = 2;
1672     }
1673
1674     // Previous row
1675     memcpy (m_szCompressBuf, m_SwathData[iCPlane][m_iNextRaster], m_iImageWidth);
1676
1677     static  BYTE    rand_table[4][4] = {{0, 3, 1, 2},
1678                                         {3, 1, 2, 0},
1679                                         {1, 2, 0, 3},
1680                                         {2, 0, 3, 1}};
1681
1682     BYTE    rt1, rt2;
1683     rt1 = m_iNextRaster % 4;
1684
1685     for (int i = 0; i < m_iImageWidth; i++)
1686     {
1687         cbyte2 = m_szCompressBuf[i];
1688         cbyte1 = (input == NULL) ? 0 : input[i];
1689
1690 //      1200 dpi raster split into 2 600 dpi rasters
1691
1692         r1b1 = 0;
1693         r1b2 = 0;
1694         r2b1 = 0;
1695         r2b2 = 0;
1696
1697         for (int ibit = 0; ibit < 8; ibit++)
1698         {
1699             c1 = (cbyte1 & bitmask[ibit]) ? 1 : 0;
1700             c2 = (cbyte2 & bitmask[ibit]) ? 1 : 0;
1701             c1 = 2 * c1 + c2;
1702
1703             rt2 = (i + ibit) % 4;
1704             rt2 = rand_table[rt1][rt2];
1705
1706             if (c1 == 2)
1707             {
1708                 if (rt2 == 0)
1709                 {
1710                     r1b1 = r1b1 | (0xff & (cbyte1 & bitmask[ibit]));
1711                     r2b2 = r2b2 | (0xff & bitmask[ibit]);
1712                 }
1713                 else if (rt2 == 1)
1714                 {
1715                     r1b2 = r1b2 | (0xff & bitmask[ibit]);
1716                     r2b1 = r2b1 | (0xff & bitmask[ibit]);
1717                 }
1718
1719                 else if (rt2 == 2)
1720                 {
1721                     r1b1 = r1b1 | (0xff & bitmask[ibit]);
1722                     r2b1 = r2b1 | (0xff & bitmask[ibit]);
1723                 }
1724                 else if (rt2 == 3)
1725                 {
1726                     r1b2 = r1b2 | (0xff & bitmask[ibit]);
1727                     r2b2 = r2b2 | (0xff & bitmask[ibit]);
1728                 }
1729
1730             }
1731             else if (c1 == 1)
1732             {
1733                 if (rt2 == 0)
1734                     r1b1 = r1b1 | (0xff & bitmask[ibit]);
1735                 else if (rt2 == 1)
1736                     r1b2 = r1b2 | (0xff & bitmask[ibit]);
1737                 else if (rt2 == 2)
1738                     r2b1 = r2b1 | (0xff & bitmask[ibit]);
1739                 else
1740                     r2b2 = r2b2 | (0xff & bitmask[ibit]);
1741
1742             }
1743             else if (c1 == 3)
1744             {
1745                 r1b1 = r1b1 | (0xff & bitmask[ibit]);
1746                 r1b2 = r1b2 | (0xff & bitmask[ibit]);
1747                 r2b1 = r2b1 | (0xff & bitmask[ibit]);
1748                 r2b2 = r2b2 | (0xff & bitmask[ibit]);
1749             }
1750         }
1751         m_SwathData[iCPlane][m_iNextRaster][j] = r1b1;
1752         m_SwathData[iCPlane][m_iNextRaster][j+iNextBitPos] = r1b2;
1753         m_SwathData[iCPlane][m_iNextRaster+1][j]   = r2b1;
1754         m_SwathData[iCPlane][m_iNextRaster+1][j+iNextBitPos] = r2b2;
1755
1756         j += iJIncrement;
1757     }
1758 }
1759