Code sync
[external/hplip.git] / prnt / hpijs / ljzjscolor.cpp
1 /*****************************************************************************\
2   ljzjscolor.cpp : Implementation for the LJZjsColor class
3
4   Copyright (c) 1996 - 2006, Hewlett-Packard Co.
5   All rights reserved.
6
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10   1. Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12   2. Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15   3. Neither the name of Hewlett-Packard nor the names of its
16      contributors may be used to endorse or promote products derived
17      from this software without specific prior written permission.
18
19   THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
22   NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24   TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \*****************************************************************************/
30
31
32 #ifdef APDK_LJZJS_COLOR
33
34 #include "header.h"
35 #include "io_defs.h"
36 #include "printerproxy.h"
37 #include "resources.h"
38 #include "ljzjs.h"
39 #include "ljzjscolor.h"
40
41 APDK_BEGIN_NAMESPACE
42
43 #define LJZJSCOLOR2DEVICESCOUNT 8
44
45 extern uint32_t ulMapGRAY_K_6x6x1[9 * 9 * 9];
46
47 extern uint32_t ulMapDJ600_CCM_K[9 * 9 * 9];
48 extern uint32_t ulMapDJ970_KCMY[9 * 9 * 9];
49 extern unsigned char ucMapDJ4100_KCMY_Photo_BestA_12x12x1[];
50 extern unsigned char ucMapDJ4100_KCMY_Photo_BestV_12x12x1[];
51 extern unsigned char ucMapDJ4100_KCMY_BestA_12x12x1[];
52 extern unsigned char ucMapDJ4100_KCMY_BestS_12x12x1[];
53 extern BYTE *GetHT12x12x1_4100_Photo_Best ();
54
55 LJZjsColor::LJZjsColor (SystemServices* pSS, int numfonts, BOOL proto)
56     : LJZjs (pSS, numfonts, proto)
57 {
58
59         ePen = BOTH_PENS;
60
61     pMode[GRAYMODE_INDEX]    = new LJZjsColorDraftGrayMode ();
62     pMode[DEFAULTMODE_INDEX] = new LJZjsColorNormalGrayMode ();
63     pMode[SPECIALMODE_INDEX] = new LJZjsColorDraftColorMode ();
64     pMode[SPECIALMODE_INDEX+1] = new LJZjsColorNormalColorMode ();
65     ModeCount = 4;
66
67     CMYMap = NULL;
68 #ifdef  APDK_AUTODUPLEX
69     m_bRotateBackPage = FALSE;  // Lasers don't require back side image to be rotated
70 #endif
71     m_pszInputRasterData = NULL;
72     m_dwCurrentRaster = 0;
73     m_cmColorMode = GREY_K;
74     m_bStartPageSent = FALSE;
75     m_iPlaneNumber = 0;
76     m_iBPP = 2;  // Setting this to 1 will cause problems
77     for (int i = 1; i < 4; i++)
78     {
79         m_iP[i] = i - 1; //{3, 0, 1, 2};
80     }
81     m_iP[0] = 3;
82     m_bIamColor = TRUE;
83     m_iPrinterType = eLJZjsColor;
84
85         /*Checking for LJZjsColor-2 format Printers*/
86         m_bLJZjsColor2Printer = IsLJZjsColor2Printer(pSS);
87 }
88
89 LJZjsColor::~LJZjsColor ()
90 {
91 }
92
93 /*
94  *  Draft
95  *  Gray
96  */
97 LJZjsColorDraftGrayMode::LJZjsColorDraftGrayMode ()
98 : GrayMode(/*ulMapDJ600_CCM_K*/ulMapGRAY_K_6x6x1)
99 {
100
101     ResolutionX[0] =
102     ResolutionY[0] = 600;
103     BaseResX =
104     BaseResY = 600;
105     MixedRes = FALSE;
106     bFontCapable = FALSE;
107     theQuality = qualityDraft;
108     pmQuality = QUALITY_DRAFT;
109 #ifdef APDK_AUTODUPLEX
110     bDuplexCapable = TRUE;
111 #endif
112     Config.bCompress = FALSE;
113 }
114
115 /*
116  * Normal
117  * Gray
118  */
119 LJZjsColorNormalGrayMode::LJZjsColorNormalGrayMode ()
120 : GrayMode(/*ulMapDJ600_CCM_K*/ulMapGRAY_K_6x6x1)
121 {
122
123     ResolutionX[0] =
124     ResolutionY[0] = 600;
125     BaseResX =
126     BaseResY = 600;
127         TextRes  = 600;
128     MixedRes = FALSE;
129     bFontCapable = FALSE;
130 #ifdef APDK_AUTODUPLEX
131     bDuplexCapable = TRUE;
132 #endif
133     Config.bCompress = FALSE;
134 }
135
136 /*
137  * Draft
138  * Color
139  */
140 LJZjsColorDraftColorMode::LJZjsColorDraftColorMode ()
141 : PrintMode(ulMapDJ970_KCMY)
142 {
143         cmap.ulMap1 =
144         cmap.ulMap2 = NULL;
145         cmap.ulMap3 = (unsigned char *) ucMapDJ4100_KCMY_Photo_BestA_12x12x1;
146         ColorFEDTable = GetHT12x12x1_4100_Photo_Best ();
147
148     ResolutionX[0] = ResolutionY[0] = 600;
149     BaseResX = BaseResY = 600;
150     TextRes = 600;
151     MixedRes = FALSE;
152     bFontCapable = FALSE;
153     pmQuality = QUALITY_DRAFT;
154     theQuality = qualityDraft;
155 #ifdef APDK_AUTODUPLEX
156     bDuplexCapable = TRUE;
157 #endif
158     Config.bCompress = FALSE;
159 }
160
161
162 /*
163  * Normal
164  * Color
165  */
166 LJZjsColorNormalColorMode::LJZjsColorNormalColorMode ()
167 : PrintMode(ulMapDJ970_KCMY)
168 {
169         cmap.ulMap1 =
170         cmap.ulMap2 = NULL;
171         cmap.ulMap3 = (unsigned char *) ucMapDJ4100_KCMY_Photo_BestA_12x12x1;
172     
173         ColorFEDTable = GetHT12x12x1_4100_Photo_Best ();
174
175     for (int i = 0; i < 4; i++)
176     {
177         ColorDepth[i] = 1;
178
179         ResolutionX[i] = 600;
180         ResolutionY[i] = 600;
181     }
182 //    ColorDepth[0] = 1;
183     ResolutionX[0] =
184     ResolutionY[0] = 600;
185     BaseResX       =
186     BaseResY       = 600;
187     TextRes        = 600;
188     MixedRes = FALSE;
189     bFontCapable = FALSE;
190     pmQuality = QUALITY_NORMAL;
191 #ifdef APDK_AUTODUPLEX
192     bDuplexCapable = TRUE;
193 #endif
194     Config.bCompress = FALSE;
195 }
196
197 DRIVER_ERROR LJZjsColor::Encapsulate (const RASTERDATA *pRasterData, BOOL bLastPlane)
198 {
199         DRIVER_ERROR err = NO_ERROR;
200     if( m_cmColorMode == COLOR )
201     {
202         if (pRasterData != NULL)
203         {
204             BYTE        *p = m_pszCurPtr + (m_iP[m_iPlaneNumber] * m_dwWidth * m_iBPP) * m_dwLastRaster;
205             for (int i = 0; i < pRasterData->rastersize[COLORTYPE_COLOR]; i++)
206             {
207                 p[i*m_iBPP] = szByte1[pRasterData->rasterdata[COLORTYPE_COLOR][i]];
208                 p[i*m_iBPP+1] = szByte2[pRasterData->rasterdata[COLORTYPE_COLOR][i]];
209                 p[i*m_iBPP] |= (p[i*m_iBPP] >> 1);
210                 p[i*m_iBPP+1] |= (p[i*m_iBPP+1] >> 1);
211             }
212         }
213         m_iPlaneNumber++;
214
215         if (bLastPlane)
216         {
217             m_dwCurrentRaster++;
218             m_pszCurPtr += m_iBPP * m_dwWidth;
219             m_iPlaneNumber = 0;
220         }
221         
222     }
223     else
224     {
225         if (pRasterData != NULL)
226         {
227             for (int i = 0; i < pRasterData->rastersize[COLORTYPE_COLOR]; i++)
228             {
229                 m_pszCurPtr[i*m_iBPP]   = szByte1[pRasterData->rasterdata[COLORTYPE_COLOR][i]];
230                 m_pszCurPtr[i*m_iBPP+1] = szByte2[pRasterData->rasterdata[COLORTYPE_COLOR][i]];
231                 m_pszCurPtr[i*m_iBPP]   |= (m_pszCurPtr[i*m_iBPP] >> 1);
232                 m_pszCurPtr[i*m_iBPP+1] |= (m_pszCurPtr[i*m_iBPP+1] >> 1);
233             }
234         }
235         
236         m_dwCurrentRaster++;
237         m_pszCurPtr += (m_iBPP * m_dwWidth);
238     }
239
240     if (m_dwCurrentRaster == m_dwLastRaster)
241     {
242                 if(TRUE == m_bLJZjsColor2Printer)
243                 {
244                         err = JbigCompress_LJZjsColor2 ();
245                 }
246                 else
247                 {
248                         err = JbigCompress();
249                 }
250     }
251     return err;
252 }
253
254 DRIVER_ERROR LJZjsColor::EndPage ()
255 {
256     DRIVER_ERROR        err = NO_ERROR;
257     BYTE                szStr[256];
258     int                 i = 0;
259     int                 iCol = (m_cmColorMode == COLOR) ? 1 : 0;
260
261     i = SendChunkHeader (szStr, 112, ZJT_END_PAGE, 8);
262     for (int j = 0; j < 8; j++)
263     {
264         i += SendItem (szStr+i, ZJIT_UINT32, 0x8200+j, (j % 4 == 3) ? 1 : iCol);
265     }
266     err = Send ((const BYTE *) szStr, 112);
267
268     m_bStartPageSent = FALSE;
269
270     m_dwCurrentRaster = 0;
271     m_pszCurPtr = m_pszInputRasterData;
272
273     return err;
274 }
275
276 /*
277 SendPlaneData
278 Description: Call the appropriate SendPlaneData based on whether its LJZjsColor-2 printer or not
279 Arguments:
280 se: Not used for LJZjsColor-2 printer. Otherwise used to send header for last stride
281 pcBuff: Pointer to struct having Compressed Data and size
282 bLastStride: Last scan line. Not used for LJZjsColor-2 printer. Used to send header otherwise.
283 */
284 DRIVER_ERROR LJZjsColor::SendPlaneData (int iPlaneNumber, HPLJZjsJbgEncSt *se, HPLJZjcBuff *pcBuff, BOOL bLastStride)
285 {
286         DRIVER_ERROR        err = NO_ERROR;
287         if(TRUE == m_bLJZjsColor2Printer)
288         {
289                 err = SendPlaneData_LJZjsColor2 (iPlaneNumber,se, pcBuff,bLastStride);
290         }
291         else
292         {
293                 err = SendPlaneData_LJZjsColor (iPlaneNumber, se, pcBuff, bLastStride);
294         }
295         return err;
296 }
297
298 DRIVER_ERROR LJZjsColor::SendPlaneData_LJZjsColor (int iPlaneNumber, HPLJZjsJbgEncSt *se, HPLJZjcBuff *pcBuff, BOOL bLastStride)
299 {
300     DRIVER_ERROR        err = NO_ERROR;
301     BYTE                szStr[256];
302     static    BOOL      bNotSent = TRUE;
303     int                 kEnd = (m_cmColorMode == COLOR) ? 5 : 2;
304     int                 i = 0;
305
306     /*
307      *  Send JBIG header info
308      */
309
310     // Send out the JBIG header if first plane and it hasn't already been sent out yet.
311     if (iPlaneNumber == 1 && bNotSent)
312     {
313         bNotSent = FALSE;
314         i = 0;
315         for (int k = 1; k < kEnd; k++)
316         {
317             i = SendChunkHeader (szStr, 132, ZJT_BITMAP, 8);
318             szStr[13] += 20;
319             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_BITMAP_TYPE, 1);
320             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_BITMAP_PIXELS, se->xd);
321             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_BITMAP_STRIDE, se->xd);
322             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_BITMAP_LINES, se->yd);
323             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_BITMAP_BPP, 1);
324             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_VIDEO_BPP, m_iBPP);
325             i += SendItem (szStr+i, ZJIT_UINT32, ZJI_PLANE, 
326                            (m_cmColorMode == COLOR) ? k : 4);
327             i += SendItem (szStr+i, ZJIT_BYTELUT, ZJI_ENCODING_DATA, 20, 20);
328             szStr[i++] = se->dl;
329             szStr[i++] = se->d;
330             szStr[i++] = se->planes;
331             szStr[i++] = 0;
332             for (int j = 3; j >= 0; j--)
333             {
334                 szStr[i] = (BYTE) ((se->xd  >> (8 * j)) & 0xFF);
335                 szStr[4+i] = (BYTE) ((se->yd  >> (8 * j)) & 0xFF);
336                 szStr[8+i] = (BYTE) ((se->l0  >> (8 * j)) & 0xFF);
337                 i++;
338             }
339             i += 8;
340
341             szStr[i++] = se->mx;
342             szStr[i++] = se->my;
343             szStr[i++] = se->order;
344             szStr[i++] = se->options;
345             err = Send ((const BYTE *) szStr, 132);
346             ERRCHECK;
347         }
348     }
349
350     BYTE    *p = pcBuff->pszCompressedData + 20;
351     int     dwNumItems;
352     int     dwSize;
353
354     pcBuff->dwTotalSize -= 20;
355     int     iPadCount = 0;
356
357     i = 0;
358     if (pcBuff->dwTotalSize % 4)
359     {
360         iPadCount = ((pcBuff->dwTotalSize / 4 + 1) * 4) - pcBuff->dwTotalSize;
361     }
362
363     dwSize = 16 + pcBuff->dwTotalSize + iPadCount;
364     dwNumItems = 1;
365     if (bLastStride)
366     {
367         dwNumItems = 3;
368         bNotSent = TRUE;
369     }
370     dwSize += (dwNumItems * 12);
371     i = SendChunkHeader (szStr, dwSize, ZJT_BITMAP, dwNumItems);
372     i += SendItem (szStr+i, ZJIT_UINT32, ZJI_PLANE, (kEnd == 5) ? iPlaneNumber : 4);
373     if (bLastStride)
374     {
375         i += SendItem (szStr+i, ZJIT_UINT32, ZJI_BITMAP_LINES, se->yd);
376         i += SendItem (szStr+i, ZJIT_UINT32, ZJI_END_PLANE, bLastStride);
377     }
378     err = Send ((const BYTE *) szStr, i);
379     ERRCHECK;
380         
381     err = Send ((const BYTE *) p, pcBuff->dwTotalSize);
382     ERRCHECK;
383     if (iPadCount != 0)
384     {
385         memset (szStr, 0, iPadCount);
386         err = Send ((const BYTE *) szStr, iPadCount);
387     }
388
389     return err;
390 }
391
392
393
394 /*SendPlaneData for LJZjsColor-2 printer
395 Description: Send the compressed data for the particular plane. Data sent in chunks of max size 64k
396 or 0x10000
397 Arguments:
398 se: Not used for LJZjsColor-2 printer
399 pcBuff: Pointer to struct having Compressed Data and size
400 bLastStride: Last scan line. Not used for LJZjsColor-2 printer.
401 */
402 DRIVER_ERROR LJZjsColor::SendPlaneData_LJZjsColor2 (int iPlaneNumber, HPLJZjsJbgEncSt *se, HPLJZjcBuff *pcBuff, BOOL bLastStride)
403 {
404     DRIVER_ERROR        err = NO_ERROR;
405     BYTE                        szStr[256];                     /*Buffer to send commands*/
406     
407     BYTE                        *pbJBigData = NULL;
408     
409     DWORD                       dwDataSize = 0;                         /*Holds the total size of compressed bytes to Send*/
410         DWORD                   dwMaxChunkSize = 0x10000;       /*1 chunk can send 64k bytes. 64k = 0x10000*/
411         DWORD                   dwCurrentChunkSize = 0;
412         DWORD                   dwLoopCount = 0;
413
414         int                             iPadCount = 0;
415         int                             nByteCount = 0;
416
417         bool                    bLastChunk = FALSE;
418     
419         memset (szStr, 0, sizeof(szStr));
420         
421         /*Start Plane with item Plane*/
422     nByteCount = SendChunkHeader (szStr, 28, ZJT_START_PLANE, 1);
423         nByteCount += SendItem (szStr+nByteCount, ZJIT_UINT32, ZJI_PLANE,iPlaneNumber);
424         
425         /**** Send JBIG header info ****/
426         nByteCount += SendChunkHeader (szStr+nByteCount, 36, ZJT_JBIG_BIH, 0);
427         err = Send ((const BYTE *) szStr, nByteCount);
428     ERRCHECK;
429
430         pbJBigData = pcBuff->pszCompressedData;
431         err = Send ((const BYTE *) pbJBigData, 20);
432     ERRCHECK;
433     
434         pbJBigData += 20;/*First 20 bytes was JBIG header which is done*/
435         pcBuff->dwTotalSize -= 20;
436     
437    
438     if (pcBuff->dwTotalSize % 4) /*Make Data DWORD aligned by padding if reqd.*/
439     {
440         iPadCount = ((pcBuff->dwTotalSize / 4 + 1) * 4) - pcBuff->dwTotalSize;
441     }
442
443     dwDataSize = pcBuff->dwTotalSize;
444
445         /*Send the Compressed Data in chunks of 0x10000 (~64k)*/
446         for(dwLoopCount = 0; dwLoopCount < dwDataSize ; dwLoopCount +=dwMaxChunkSize)
447         {
448                 memset (szStr, 0, sizeof(szStr));
449                 dwCurrentChunkSize = dwMaxChunkSize;
450                 
451                 if(dwLoopCount+dwCurrentChunkSize > dwDataSize)
452                 {
453                         dwCurrentChunkSize = dwDataSize - (dwLoopCount);
454                         bLastChunk = TRUE;
455                 }
456                 if (!bLastChunk)
457                 {
458                         nByteCount = SendChunkHeader (szStr, dwCurrentChunkSize + 16, ZJT_JBIG_HID, 0);
459                 }
460                 else /*For last chunk add the pad count size and send header*/
461                 {
462                         nByteCount = SendChunkHeader (szStr, dwCurrentChunkSize + 16 + iPadCount, ZJT_JBIG_HID, 0);                     
463                 }
464                 err = Send ((const BYTE *) szStr, nByteCount);
465                 ERRCHECK;
466
467                 err = Send ((const BYTE *) pbJBigData, dwCurrentChunkSize);
468                 ERRCHECK;
469                 
470                 pbJBigData+=dwCurrentChunkSize;
471         }
472         if(iPadCount != 0)
473         {
474                 memset (szStr, 0, iPadCount);
475                 err = Send ((const BYTE *) szStr, iPadCount);
476         }
477
478         memset (szStr, 0, sizeof(szStr));
479         
480         /*End JBig and then End Plane with item Plane*/
481         
482         nByteCount = SendChunkHeader (szStr, 16, ZJT_END_JBIG, 0);
483
484         nByteCount += SendChunkHeader (szStr+nByteCount, 28, ZJT_END_PLANE, 1);
485         nByteCount += SendItem (szStr+nByteCount, ZJIT_UINT32, ZJI_PLANE,iPlaneNumber);
486
487         err = Send ((const BYTE *) szStr, nByteCount);
488         ERRCHECK;
489
490     return err;
491 }
492
493 DRIVER_ERROR LJZjsColor::VerifyPenInfo()
494 {
495     ePen = BOTH_PENS;
496     return NO_ERROR;
497 }
498
499 DRIVER_ERROR LJZjsColor::ParsePenInfo (PEN_TYPE& ePen, BOOL QueryPrinter)
500 {
501     ePen = BOTH_PENS;
502
503     return NO_ERROR;
504 }
505
506 bool LJZjsColor::IsLJZjsColor2Printer(SystemServices* pSS)
507 {
508         if (pSS == NULL)
509                 return false;
510         char szLJZjsColor2ModelNames[LJZJSCOLOR2DEVICESCOUNT][25] = {
511                 "HP LaserJet CP1025\0",
512                 "HP LaserJet CP1021\0",
513                 "HP LaserJet CP1022\0",
514                 "HP LaserJet CP1023\0",
515                 "HP LaserJet CP1025nw\0",
516                 "HP LaserJet CP1026nw\0",
517                 "HP LaserJet CP1027nw\0",
518                 "HP LaserJet CP1028nw\0"
519         };      //Device models that follow LJZjsColor-2 encapsulation format
520
521         BYTE strDeviceID[DevIDBuffSize];
522         DRIVER_ERROR err;
523         bool bLJZjsColor2Printer = FALSE;
524         err = pSS->GetDeviceID(strDeviceID,DevIDBuffSize,FALSE);
525
526         for(int i=0; i< LJZJSCOLOR2DEVICESCOUNT; i++)
527         {
528                 if( NO_ERROR == err &&
529                         (strnlen((const char*)strDeviceID, DevIDBuffSize)< DevIDBuffSize) && 
530                         (strstr((const char*)strDeviceID, (const char*)szLJZjsColor2ModelNames[i])))
531                 {
532                         bLJZjsColor2Printer = TRUE;
533                         break;
534                 }
535         }
536         return bLJZjsColor2Printer;
537 }
538
539 APDK_END_NAMESPACE
540
541 #endif  // defined APDK_LJZJS_COLOR