Tizen 2.0 Release
[platform/upstream/hplip.git] / prnt / hpcups / Job.cpp
1 /*****************************************************************************\
2   Job.cpp : Implementation of Job class
3
4   Copyright (c) 1996 - 2001, 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 "Job.h"
32
33 Job::Job() :
34     m_pSys(NULL),
35     m_pPipeline(NULL),
36     m_pEncap(NULL),
37     skipcount(0),
38     m_pBlankRaster(NULL),
39     m_pBlackRaster(NULL),
40     m_bDataSent(false),
41     m_iRaster(0),
42     m_iBlanks(0)
43 {
44 }
45
46 DRIVER_ERROR Job::Init(SystemServices *pSystemServices, JobAttributes *job_attrs, Encapsulator *encap_intf)
47 {
48     DRIVER_ERROR err = NO_ERROR;
49
50     if (encap_intf == NULL) {
51         return NO_PRINTER_SELECTED;
52     }
53
54     m_pEncap = encap_intf;
55     m_pSys = pSystemServices;
56
57     //m_job_attributes = job_attrs;
58     memcpy(&m_job_attributes, job_attrs, sizeof(m_job_attributes));
59
60     err = m_pEncap->StartJob(m_pSys, &m_job_attributes);
61
62     if (err == NO_ERROR)
63         err = Configure();
64
65 //  Setup the blank raster used by sendrasters
66     if (err == NO_ERROR)
67         err = setBlankRaster();
68     return err;
69 } //Job
70
71 /*! Allows the encapsulator to prepare for a new page
72  *
73  */
74
75 DRIVER_ERROR Job::StartPage(JobAttributes *job_attrs)
76 {
77
78     if (job_attrs) {
79         memcpy(&m_job_attributes, job_attrs, sizeof(m_job_attributes));
80     }
81     return m_pEncap->StartPage(&m_job_attributes);
82 }
83
84 DRIVER_ERROR Job::Cleanup()
85 {
86     // Client isn't required to call NewPage at end of last page, so
87     // we may need to eject a page now.
88     DRIVER_ERROR    err = NO_ERROR;
89
90 /*
91  *  Let the encapsulator cleanup, such as sending previous page if speed mech
92  *  is enabled.
93  */
94
95     if (m_pEncap) {
96         err = m_pEncap->Cleanup();
97     }
98
99     if (err != NO_ERROR) {
100         return err;
101     }
102
103     if (m_bDataSent || err != NO_ERROR) {
104         NewPage();
105     }
106
107     // Tell printer that job is over.
108     if (m_pEncap) {
109         m_pEncap->EndJob();
110     }//end if
111     return NO_ERROR;
112 }
113
114 void Job::CancelJob()
115 {
116     if (m_pEncap)
117         m_pEncap->CancelJob();
118 }
119
120 Job::~Job()
121 {
122     if (m_pBlackRaster) {
123         delete [] m_pBlackRaster;
124     }
125
126     if (m_pBlankRaster) {
127         delete [] m_pBlankRaster;
128     }
129
130     Pipeline    *p;
131     Pipeline    *p2;
132     p = m_pPipeline;
133     while (p)
134     {
135         p2 = p;
136         p = p->next;
137         delete p2->Exec;
138         delete p2;
139     }
140
141     if (m_pEncap) {
142         delete m_pEncap;
143     }
144
145 } //~Job
146
147 void Job::unpackBits(BYTE *BlackImageData)
148 {
149 // Convert K from 1-bit raster to 8-bit raster.
150     unsigned char  bitflag[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
151     int    width = (m_job_attributes.media_attributes.printable_width + 7) / 8;
152     for (int i = 0; i < width; i++)
153     {
154         for (int j = 0; j < 8; j++)
155         {
156             if (BlackImageData[i] & bitflag[j])
157                 m_pBlackRaster[i*8+j] = 1;
158         }
159     }
160 }
161
162 DRIVER_ERROR Job::SendRasters(BYTE* BlackImageData, BYTE* ColorImageData)
163 {
164     DRIVER_ERROR err = NO_ERROR;
165     if (m_pPipeline == NULL) {
166         return SYSTEM_ERROR;
167     }
168
169     if (BlackImageData == NULL && ColorImageData == NULL) {
170         if (m_pEncap->CanSkipRasters()) {
171             skipcount++;
172             return NO_ERROR;
173         }
174         ColorImageData = m_pBlankRaster;
175     }
176
177     if (skipcount > 0) {
178         m_pPipeline->Flush();
179         err = m_pEncap->SendCAPy(skipcount);
180         skipcount = 0;
181     }
182     m_bDataSent = true;
183
184     if (BlackImageData || ColorImageData)
185     {
186         if (BlackImageData)
187         {
188             if (m_pEncap->UnpackBits())
189             {
190                 err = setBlackRaster();
191                 ERRCHECK;
192                 unpackBits(BlackImageData);
193                 BlackImageData = m_pBlackRaster;
194             }
195             m_pPipeline->Exec->raster.rastersize[COLORTYPE_BLACK] = m_job_attributes.media_attributes.printable_width;
196             m_pPipeline->Exec->raster.rasterdata[COLORTYPE_BLACK] = BlackImageData;
197         }
198         else
199         {
200             m_pPipeline->Exec->raster.rastersize[COLORTYPE_BLACK] = 0;
201             m_pPipeline->Exec->raster.rasterdata[COLORTYPE_BLACK] = NULL;
202         }
203         if (ColorImageData)
204         {
205             m_pPipeline->Exec->raster.rastersize[COLORTYPE_COLOR] = m_job_attributes.media_attributes.printable_width * 3;
206             m_pPipeline->Exec->raster.rasterdata[COLORTYPE_COLOR] = ColorImageData;
207         }
208         else
209         {
210             m_pPipeline->Exec->raster.rastersize[COLORTYPE_COLOR] = 0;
211             m_pPipeline->Exec->raster.rasterdata[COLORTYPE_COLOR] = NULL;
212         }
213         err = m_pPipeline->Execute(&(m_pPipeline->Exec->raster));
214     }
215
216     return err;
217 } // Sendrasters
218
219 DRIVER_ERROR Job::NewPage()
220 {
221     DRIVER_ERROR err;
222     m_pEncap->SetLastBand();
223
224     if (!m_bDataSent && skipcount > 0) {
225         skipcount = 0;
226         SendRasters(NULL, m_pBlankRaster);
227     }
228     m_pPipeline->Flush();
229     err = m_pEncap->FormFeed();
230     ERRCHECK;
231
232 //  reset flag used to see if formfeed needed
233     m_bDataSent = false;
234     skipcount = 0;
235
236     return NO_ERROR;
237 } // Newpage
238
239 DRIVER_ERROR Job::Configure()
240 {
241 // mode has been set -- now set up rasterwidths and pipeline
242     DRIVER_ERROR    err = NO_ERROR;
243     Pipeline        *p;
244
245     p = NULL;
246     // Ask Encapsulator to configure itself
247
248     err = m_pEncap->Configure(&m_pPipeline);
249     if (err != NO_ERROR)
250     {
251         return err;
252     }
253
254     // always end pipeline with RasterSender
255     // create RasterSender object
256     RasterSender    *pSender;
257     pSender = new RasterSender(m_pEncap);
258
259     p = new Pipeline(pSender);
260
261     if (m_pPipeline) {
262         m_pPipeline->AddPhase(p);
263     }
264     else {
265         m_pPipeline = p;
266     }
267    return NO_ERROR;
268 } //Configure
269
270 DRIVER_ERROR Job::setBlackRaster()
271 {
272     if (!m_pBlackRaster) {
273         m_pBlackRaster = new BYTE[m_job_attributes.media_attributes.printable_width];
274         NEWCHECK(m_pBlackRaster);
275     }
276     memset(m_pBlackRaster, 0, m_job_attributes.media_attributes.printable_width);
277
278     return NO_ERROR;
279 } //setBlackRaster
280
281 DRIVER_ERROR Job::setBlankRaster()
282 {
283     if (m_pBlankRaster) {
284         delete m_pBlankRaster;
285     }
286     size_t    size = m_job_attributes.media_attributes.printable_width * 3;
287     m_pBlankRaster = new BYTE[size];
288     NEWCHECK(m_pBlankRaster);
289     memset(m_pBlankRaster, 0xFF, size);
290     return NO_ERROR;
291 }
292
293 DRIVER_ERROR Job::preProcessRasterData(cups_raster_t **ppcups_raster, cups_page_header2_t* firstpage_cups_header, char* pPreProcessedRasterFile)
294 {
295         dbglog ("DEBUG: Job::preProcessRasterData.............. \n");
296         return m_pEncap->preProcessRasterData(ppcups_raster, firstpage_cups_header, pPreProcessedRasterFile);
297 }
298    
299