1 /*###########################################################
2 *
3 *  Copyright (c) HP Company, 2006.
4 *  All rights reserved.  Copying or other reproduction of this
5 *  program except for archival purposes is prohibited without
6 *  the prior written consent of HP Company.
7 *
8 *  File: genPCLm.c
9 *
10 *  HP COMPANY
11 *  11311 Chinden Boulevard
12 *  Boise, Idaho  83714
13 *
14 *##########################################################*/
15 
16 /**********************************************************************************************
17 * File: genPCLm.c
18 *
19 * Author(s): Steve Claiborne
20 *
21 * To Do:								Status
22 *   - Error generation
23 *   - Backside duplex flip/mirror capability
24 *   - Opportunity to scale input image to device resolution
25 *   - Support Adobe RGB color space
26 *   - Skip white strips
27 *
28 *====  COMPLETED TASKS ===========================================================
29 *   - Generate output file name to reflect media and input params       12/20/2010
30 *   - Support 300 device resolution                                     12/17/2010
31 *   - Support 1200 device resolution                                    12/17/2010
32 *   - Media size support                                                12/17/2010
33 *   - Other compression technologies: delta, taos                       11/17/2010
34 *     - zlib 								11/17/2010
35 *     - RLE (Hi)					                12/13/2010
36 *   - Margin support                                                    N/A?
37 *   - Strip height programmability                                      11/18/2010
38 *   - Multiple pages                                                    11/23/2010
39 *   - Source image scaling 						11/09/2010
40 *   - Debug option							11/09/2010
41 *   - Add comment job ticket                                            12/02/2010
42 *   - Added grayscale                                                   12/20/2010
43 *   - Scaled source width to full-width of media                        12/17/2010
44 *   - Implemented PCLmGen OO Interface					02/10/2011
45 *   - AdobeRGB                                                          02/01/2011
46 *   - Support odd-page duplex for InkJet                                02/01/2011
47 *   - JPEG markers to reflect resolution                                02/16/2011
48 *   - JPEG markers for strip height are stuck at 16                     02/16/2011
49 *   - KidsArray, xRefTable, KidsString, pOutBuffer are static sized     02/23/2011
50 *   - Rewrite the logic for handling the **bufPtr                       02/24/2011
51 *   - Support short-edge duplex                                         03/04/2011
52 *   - Need to implement error handling correctly    			03/04/2011
53 *   - Fixed adobeRGB multi-job issue                                    03/08/2011
54 *   - Color convert crash fix                                           03/08/2011
55 *   - Added abilty to pass debug setting to genPCLm			03/08/2011
56 *   - Added top-margin capabilities to shift image right and down	04/12/2011
57 *   - Add ability to use PNG as input                                   04/01/2011
58 **********************************************************************************
59 *   - eliminate the flate_colorspace.bin file
60 *   - Change compression types intra-page
61 *   - Assert that CS does not change
62 *   - Change CS type on page boundaries
63 *   - Implement the media*Offset functionality
64 *   - Leftover lines in a strip are not supported
65 *   - Need to implement debug -> logfile
66 *
67 *====  Log of issues / defects  ==================================================
68 * 0.54: programmable strip height                                       11/23/2010
69 * 0.53: run-time crash of large source images                           11/17/2010
70 *       switched to getopt for parsing                                  11/17/2010
71 * 0.55: Add multi-page support						11/23/2010
72 * 0.56: Fixing /Length issue & removed leading comment                  11/29/2010
73 * 0.57: Fixing scaling and image position issues                        12/01/2010
74 * 0.58: Fixing white space at bottom of page                            12/01/2010
75 * 0.58: Fixing floating point error by switching to dev coordinates     12/02/2010
76 * 0.59: Added comment job-ticket                                        12/03/2010
77 * 0.60: Fixed xref issues that caused performance degradation           12/08/2010
78 *       Added support for -h 0 (generates 1 strip)                      12/08/2010
79 *       Added JPEG compression into JFIF header                         12/08/2010
80 * 0.63  Fixed media-padding issue for mediaHeight			12/20/2010
81 *       Fixed media-padding issue for non-600 resolutions		12/20/2010
82 * 0.65  Added ability to inject blank page for duplex			02/02/2011
83 *
84 * Known Issues:
85 *   - Can't convert large images to PDF					Fixed 11/18(0.53)
86 *   - 1200 dpi images are rendered to PDF at 600 dpi                    Fixed 12/17(0.61)
87 *
88 **********************************************************************************************/
89 
90 /**********************************************************************************************
91 * JPEG image pointers:
92 *   - myImageBuffer: allocated source image buffer
93 *   - destBuffer:    current buffer pointer for put_scanline_someplace
94 *
95 **********************************************************************************************/
96 
97 /**********************************************************************************************
98 * zlib parameters
99 * compress2 (dest, destLen, source, sourceLen)
100 *  Compresses the source buffer into the destination buffer.  sourceLen is the byte
101 *  length of the source buffer. Upon entry, destLen is the total size of the
102 *  destination buffer, which must be at least 0.1% larger than sourceLen plus
103 *  12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
104 
105 *  compress returns Z_OK if success, Z_MEM_ERROR if there was not enough
106 *  memory, Z_BUF_ERROR if there was not enough room in the output buffer,
107 *  Z_STREAM_ERROR if the level parameter is invalid.
108 *    #define Z_OK            0
109 *    #define Z_STREAM_END    1
110 *    #define Z_NEED_DICT     2
111 *    #define Z_ERRNO        (-1)
112 *    #define Z_STREAM_ERROR (-2)
113 *    #define Z_DATA_ERROR   (-3)
114 *    #define Z_MEM_ERROR    (-4)
115 *    #define Z_BUF_ERROR    (-5)
116 *    #define Z_VERSION_ERROR (-6)
117 *
118 **********************************************************************************************/
119 #define STAND_ALLONE
120 
121 #include "PCLmGenerator.h"
122 #include "CommonDefinitions.h"
123 #include "./../../common/utils.h"
124 #include <stdio.h>
125 #include <stdlib.h>
126 #include <string.h>
127 #include <fcntl.h>
128 #include <assert.h>
129 #include <math.h>
130 #include <zlib.h>
131 //#include <unistd.h>
132 
133 extern "C"
134 {
135 #include "jpeglib.h"
136 }
137 #include "RunLenEncoding.h"
138 
139 #include "common_defines.h"
140 #include "genPCLm.h"
141 #include "ctype.h"
142 
143 #include "flate_colorspace.h"
144 /*
145 Defines
146 */
147 
148 int debugIt = 0;
149 
150 #define STRIP_HEIGHT 16
151 #define JPEG_QUALITY 100
152 
153 #define XREF_SIZE 10000
154 #define TEMP_BUFF_SIZE 100000
155 #define DEFAULT_OUTBUFF_SIZE 64*5120*3
156 
157 #define STANDARD_SCALE_FOR_PDF 72.0
158 
159 #define KID_STRING_SIZE 1000
160 
161 #define CATALOG_OBJ_NUMBER 1
162 #define PAGES_OBJ_NUMBER   2
163 
164 /*
165 Local Variables
166 */
167 
168 /*
169 Defines
170 */
171 #define rgb_2_gray(r,g,b) (ubyte)(0.299*(double)r+0.587*(double)g+0.114*(double)b)
172 
173 // Note: this is required for debugging
174 boolean writeOutputFile(int numBytes, ubyte *ptr, char *user_name);
175 
176 /*
177 ********************************************* Helper Routines **************************
178 */
179 
180 /*
181 Function: shiftStripByLeftMargin
182 Purpose:  To shift the strip image right in the strip buffer by leftMargin pixels
183 Assumptions: The strip buffer was allocated large enough to handle the shift; if not
184 then the image data on the right will get clipped.
185 Details:
186 We allocate a full strip (height and width), but then only copy numLinesThisCall from the original buffer
187 to the newly allocated buffer.  This pads the strips for JPEG processing.
188 */
shiftStripByLeftMargin(ubyte * ptrToStrip,sint32 currSourceWidth,sint32 currStripHeight,sint32 numLinesThisCall,sint32 currMediaWidth,sint32 leftMargin,colorSpaceDisposition destColorSpace)189 ubyte *shiftStripByLeftMargin(ubyte *ptrToStrip,sint32 currSourceWidth,sint32 currStripHeight, sint32 numLinesThisCall,
190 							  sint32 currMediaWidth, sint32 leftMargin, colorSpaceDisposition destColorSpace)
191 {
192 	ubyte *fromPtr=ptrToStrip, *toPtr, *newStrip;
193 	sint32 scanLineWidth;
194 
195 	assert(currSourceWidth+(2*leftMargin)<=currMediaWidth);
196 
197 	// writeOutputFile(currSourceWidth*3*numLinesThisCall, ptrToStrip,"");
198 
199 	if(destColorSpace==grayScale)
200 	{
201 		scanLineWidth=currMediaWidth;
202 		// Allocate a full strip
203 		newStrip=(ubyte*)malloc(scanLineWidth*currStripHeight);
204 		memset(newStrip,0xff,scanLineWidth*currStripHeight);
205 
206 		for(int i=0;i<numLinesThisCall;i++)
207 		{
208 			toPtr=newStrip+leftMargin+(i*currMediaWidth);
209 			fromPtr=ptrToStrip+(i*currSourceWidth);
210 			memcpy(toPtr,fromPtr,currSourceWidth);
211 		}
212 
213 	}
214 	else
215 	{
216 		scanLineWidth=currMediaWidth*3;
217 		sint32 srcScanlineWidth=currSourceWidth*3;
218 		sint32 shiftAmount=leftMargin*3;
219 		newStrip=(ubyte*)malloc(scanLineWidth*currStripHeight);
220 		memset(newStrip,0xff,scanLineWidth*currStripHeight);
221 		for(int i=0;i<numLinesThisCall;i++)
222 		{
223 			toPtr=newStrip+shiftAmount+(i*scanLineWidth);
224 			fromPtr=ptrToStrip+(i*srcScanlineWidth);
225 			memcpy(toPtr,fromPtr,srcScanlineWidth);
226 			// memset(toPtr,0xe0,srcScanlineWidth);
227 		}
228 	}
229 
230 	return(newStrip);
231 }
232 
233 #ifdef SUPPORT_WHITE_STRIPS
isWhiteStrip(void * pInBuffer,int inBufferSize)234 bool PCLmGenerator::isWhiteStrip(void *pInBuffer, int inBufferSize)
235 {
236 	uint32 *ptr=(uint32*)pInBuffer;
237 	for(int i=0;i<inBufferSize/4;i++,ptr++)
238 	{
239 		if(*ptr!=0xffffffff)
240 			return(false);
241 	}
242 	return(true);
243 }
244 #endif
245 
246 /*Called in errorOutAndCleanUp and Destructor*/
Cleanup(void)247 void PCLmGenerator::Cleanup(void)
248 {
249 	if(allocatedOutputBuffer)
250 	{
251 		free(allocatedOutputBuffer);
252 		allocatedOutputBuffer = NULL;
253 		currOutBuffSize = 0;
254 	}
255 
256 	if(leftoverScanlineBuffer)
257 	{
258 		free(leftoverScanlineBuffer);
259 		leftoverScanlineBuffer=NULL;
260 	}
261 	if(scratchBuffer)
262 	{
263 		free(scratchBuffer);
264 		scratchBuffer = NULL;
265 	}
266 	if(xRefTable)
267 	{
268 		free(xRefTable);
269 		xRefTable=NULL;
270 	}
271 	if(KidsArray)
272 	{
273 		free(KidsArray);
274 		KidsArray=NULL;
275 	}
276 }
277 
errorOutAndCleanUp()278 int PCLmGenerator::errorOutAndCleanUp()
279 {
280 	Cleanup();
281 	jobOpen=job_errored;
282 	return(genericFailure);
283 }
284 
addXRef(sint32 xRefObj)285 bool PCLmGenerator::addXRef(sint32 xRefObj)
286 {
287 #define XREF_ARRAY_SIZE 100
288 	sint32      *tmpxRefTable = NULL;
289 	if(!xRefTable)
290 	{
291 		xRefTable=(sint32*)malloc(XREF_ARRAY_SIZE*sizeof(sint32));
292 		assert(xRefTable);
293 		if(NULL == xRefTable)
294 		{
295 			return false;
296 		}
297 		xRefTable[0]=0;
298 		xRefIndex++;
299 	}
300 
301 	xRefTable[xRefIndex]=xRefObj;
302 	xRefIndex++;
303 
304 	if(!(xRefIndex%XREF_ARRAY_SIZE))
305 	{
306 		tmpxRefTable=(sint32*)realloc(xRefTable,(((xRefIndex+XREF_ARRAY_SIZE)*sizeof(sint32))));
307 		if( NULL != tmpxRefTable)
308 		{
309 			xRefTable = tmpxRefTable;
310 		}
311 		/* if(DebugIt)
312 		printf("Realloc xRef: 0x%lx\n",(unsigned long int)xRefTable);*/
313 	}
314 	return(true);
315 }
316 
317 
addKids(sint32 kidObj)318 bool PCLmGenerator::addKids(sint32 kidObj)
319 {
320 #define KID_ARRAY_SIZE 20
321 	sint32      *tmpKidsArray = NULL;
322 	if(!KidsArray)
323 	{
324 		KidsArray=(sint32*)malloc(KID_ARRAY_SIZE*sizeof(sint32));
325 		assert(KidsArray);
326 		if(NULL == KidsArray)
327 		{
328 			return false;
329 		}
330 	}
331 
332 	KidsArray[numKids]=kidObj;
333 	numKids++;
334 
335 	if(!(numKids%KID_ARRAY_SIZE))
336 	{
337 		tmpKidsArray=(sint32*)realloc(KidsArray,((numKids+KID_ARRAY_SIZE)*sizeof(sint32)));
338 		if( NULL != tmpKidsArray)
339 		{
340 			KidsArray = tmpKidsArray;
341 		}
342 	}
343 	return(true);
344 }
345 
writeOutputFile(int numBytes,ubyte * ptr,char * user_name)346 boolean writeOutputFile(int numBytes, ubyte *ptr, char *user_name)
347 {
348 	FILE *outputFile;
349 	char outFileName[MAX_FILE_PATH_LEN];
350 	static int fileCntr=0;
351 
352 	if(1)
353 		return TRUE;
354 	snprintf(outFileName,sizeof(outFileName),"%s/hp_%s_cups_outfile_%04d",CUPS_TMP_DIR, user_name, fileCntr);
355 
356 	fileCntr++;
357 
358 	// Open output PDF file
359 	if (!(outputFile = fopen (outFileName, "w")))
360 	{
361 		dbglog ("Could not open the output file out.\n");
362 		exit (-1);
363 		//return(true);
364 	}
365 	fwrite(ptr,numBytes,1,outputFile);
366 	fclose(outputFile);
367 	return(TRUE);
368 }
369 
initOutBuff(char * buff,sint32 size)370 void PCLmGenerator::initOutBuff(char *buff, sint32 size)
371 {
372 	currBuffPtr=outBuffPtr=buff;
373 	outBuffSize=size;
374 	totalBytesWrittenToCurrBuff=0;
375 	memset(buff,0,size);
376 }
377 
378 
writeStr2OutBuff(char * str)379 void PCLmGenerator::writeStr2OutBuff(char *str)
380 {
381 	sint32 strSize=strlen(str);
382 	// Make sure we have enough room for the copy
383 	char *maxSize=currBuffPtr+strSize;
384 	assert(maxSize-outBuffPtr < outBuffSize);
385 	memcpy(currBuffPtr,str,strSize);
386 	currBuffPtr+=strSize;
387 	totalBytesWrittenToCurrBuff+=strSize;
388 	totalBytesWrittenToPCLmFile+=strSize;
389 }
390 
write2Buff(ubyte * buff,int buffSize)391 void PCLmGenerator::write2Buff(ubyte *buff, int buffSize)
392 {
393 	char *maxSize=currBuffPtr+buffSize;
394 	assert(maxSize-outBuffPtr < outBuffSize);
395 	memcpy(currBuffPtr,buff,buffSize);
396 	currBuffPtr+=buffSize;
397 	totalBytesWrittenToCurrBuff+=buffSize;
398 	totalBytesWrittenToPCLmFile+=buffSize;
399 }
400 
statOutputFileSize()401 int PCLmGenerator::statOutputFileSize()
402 {
403 	addXRef(totalBytesWrittenToPCLmFile);
404 	return(1);
405 }
406 
writePDFGrammarTrailer(int imageWidth,int imageHeight)407 void PCLmGenerator::writePDFGrammarTrailer(int imageWidth, int imageHeight)
408 {
409 	int i;
410 	char KidsString[KID_STRING_SIZE];
411 	if(DebugIt2)
412 	{
413 		dbglog("imageWidth=%d\n",imageWidth);
414 		dbglog("imageHeight=%d\n",imageHeight);
415 	}
416 
417 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Object 1 - Catalog\n"); writeStr2OutBuff(pOutStr);
418 	statOutputFileSize();
419 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", CATALOG_OBJ_NUMBER); writeStr2OutBuff(pOutStr);
420 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
421 	snprintf(pOutStr,OUT_STR_SIZE,"/Type /Catalog\n"); writeStr2OutBuff(pOutStr);
422 	snprintf(pOutStr,OUT_STR_SIZE,"/Pages %d 0 R\n",PAGES_OBJ_NUMBER); writeStr2OutBuff(pOutStr);
423 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
424 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
425 
426 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Object 2 - page tree \n"); writeStr2OutBuff(pOutStr);
427 	statOutputFileSize();
428 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", PAGES_OBJ_NUMBER); writeStr2OutBuff(pOutStr);
429 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
430 	snprintf(pOutStr,OUT_STR_SIZE,"/Count %d\n",numKids); writeStr2OutBuff(pOutStr);
431 
432 	// Define the Kids for this document as an indirect array
433 	snprintf(KidsString,KID_STRING_SIZE,"/Kids [ ");writeStr2OutBuff(KidsString);
434 	for(i=0;i<numKids && KidsArray;i++)
435 	{
436 		//spot=strlen(KidsString);
437 		snprintf(KidsString,KID_STRING_SIZE,"%d 0 R ",KidsArray[i]);
438 		writeStr2OutBuff(KidsString);
439 	}
440 
441 	snprintf(KidsString,KID_STRING_SIZE,"]\n");
442 	writeStr2OutBuff(KidsString);
443 
444 
445 	snprintf(pOutStr,OUT_STR_SIZE,"/Type /Pages\n"); writeStr2OutBuff(pOutStr);
446 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
447 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
448 
449 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: cross-reference section: object 0, 6 entries\n"); writeStr2OutBuff(pOutStr);
450 	statOutputFileSize();
451 	xRefStart=xRefIndex-1;
452 	infoObj=xRefIndex;
453 
454 	snprintf(pOutStr,OUT_STR_SIZE,"xref\n"); writeStr2OutBuff(pOutStr);
455 	snprintf(pOutStr,OUT_STR_SIZE,"0 %d\n",1); writeStr2OutBuff(pOutStr);
456 
457 	snprintf(pOutStr,OUT_STR_SIZE,"0000000000 65535 f\n"); writeStr2OutBuff(pOutStr);
458 	snprintf(pOutStr,OUT_STR_SIZE,"%d %d\n",PAGES_OBJ_NUMBER+1,xRefIndex-4); writeStr2OutBuff(pOutStr);
459 	for(i=1;i<xRefIndex-3 && xRefTable;i++)
460 	{
461 		snprintf(pOutStr,OUT_STR_SIZE,"%010d %05d n\n",xRefTable[i],0); writeStr2OutBuff(pOutStr);
462 	}
463 
464 #ifdef PIECEINFO_SUPPORTED
465 	// HP PieceInfo Structure
466 	snprintf(pOutStr,OUT_STR_SIZE,"9996 0 obj\n"); writeStr2OutBuff(pOutStr);
467 	snprintf(pOutStr,OUT_STR_SIZE,"<</HPDefine1 1\n"); writeStr2OutBuff(pOutStr);
468 	snprintf(pOutStr,OUT_STR_SIZE,"/Private 9997 0 R>>\n"); writeStr2OutBuff(pOutStr);
469 	snprintf(pOutStr,OUT_STR_SIZE,"9997 0 obj\n"); writeStr2OutBuff(pOutStr);
470 #endif
471 	//snprintf(pOutStr,OUT_STR_SIZE,"<</AIMetaData 32 0 R/AIPDFPrivateData1 33 0 R/AIPDFPrivateData10 34 0\n");
472 
473 	// Now add the catalog and page object
474 	snprintf(pOutStr,OUT_STR_SIZE,"%d 2\n",CATALOG_OBJ_NUMBER); writeStr2OutBuff(pOutStr);
475 	if(xRefTable)
476 	{
477 		snprintf(pOutStr,OUT_STR_SIZE,"%010d %05d n\n",xRefTable[xRefIndex-3],0); writeStr2OutBuff(pOutStr);
478 		snprintf(pOutStr,OUT_STR_SIZE,"%010d %05d n\n",xRefTable[xRefIndex-2],0); writeStr2OutBuff(pOutStr);
479 	}
480 
481 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: File Trailer\n"); writeStr2OutBuff(pOutStr);
482 	snprintf(pOutStr,OUT_STR_SIZE,"trailer\n"); writeStr2OutBuff(pOutStr);
483 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
484 	// snprintf(pOutStr,OUT_STR_SIZE,"/Info %d 0\n", infoObj); writeStr2OutBuff(pOutStr);
485 	snprintf(pOutStr,OUT_STR_SIZE,"/Size %d\n", xRefIndex-1); writeStr2OutBuff(pOutStr);
486 	snprintf(pOutStr,OUT_STR_SIZE,"/Root %d 0 R\n",CATALOG_OBJ_NUMBER); writeStr2OutBuff(pOutStr);
487 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
488 	snprintf(pOutStr,OUT_STR_SIZE,"startxref\n"); writeStr2OutBuff(pOutStr);
489 	if(xRefTable)
490 	{
491 		snprintf(pOutStr,OUT_STR_SIZE,"%d\n",xRefTable[xRefStart]); writeStr2OutBuff(pOutStr);
492 	}
493 	snprintf(pOutStr,OUT_STR_SIZE,"%%%%EOF\n"); writeStr2OutBuff(pOutStr);
494 }
495 
injectAdobeRGBCS()496 bool PCLmGenerator::injectAdobeRGBCS()
497 {
498 	if(adobeRGBCS_firstTime)
499 	{
500 		// We need to inject the ICC object for AdobeRGB
501 		snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: ICC Profile\n"); writeStr2OutBuff(pOutStr);
502 		statOutputFileSize();
503 		snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
504 		snprintf(pOutStr,OUT_STR_SIZE,"[/ICCBased %d 0 R]\n",objCounter); writeStr2OutBuff(pOutStr);
505 
506 		snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
507 		statOutputFileSize();
508 		snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
509 		snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
510 		snprintf(pOutStr,OUT_STR_SIZE,"/N 3\n"); writeStr2OutBuff(pOutStr);
511 		snprintf(pOutStr,OUT_STR_SIZE,"/Alternate /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
512 		snprintf(pOutStr,OUT_STR_SIZE,"/Length %u\n",ADOBE_RGB_SIZE+1); writeStr2OutBuff(pOutStr);
513 		snprintf(pOutStr,OUT_STR_SIZE,"/Filter /FlateDecode\n"); writeStr2OutBuff(pOutStr);
514 		snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
515 		snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
516 
517 		write2Buff(flateBuffer,ADOBE_RGB_SIZE);
518 
519 		snprintf(pOutStr,OUT_STR_SIZE,"\nendstream\n"); writeStr2OutBuff(pOutStr);
520 		snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
521 	}
522 
523 	adobeRGBCS_firstTime=false;
524 	return(true);
525 }
526 
527 /****************************************************************************************
528 * Function: colorConvertSource
529 * Purpose: to convert an image from one color space to another.
530 * Limitations:
531 *   - Currently, only supports RGB->GRAY
532 *****************************************************************************************/
colorConvertSource(colorSpaceDisposition srcCS,colorSpaceDisposition dstCS,ubyte * strip,sint32 stripWidth,sint32 stripHeight)533 bool PCLmGenerator::colorConvertSource(colorSpaceDisposition srcCS, colorSpaceDisposition dstCS, ubyte *strip, sint32 stripWidth, sint32 stripHeight)
534 {
535 	if(srcCS==deviceRGB && dstCS==grayScale)
536 	{
537 		// Do an inplace conversion from RGB -> 8 bpp gray
538 		ubyte *srcPtr=strip;
539 		ubyte *dstPtr=strip;
540 		for(int h=0;h<stripHeight;h++)
541 		{
542 			for(int w=0;w<stripWidth;w++,dstPtr++,srcPtr+=3)
543 			{
544 				//*dstPtr=(ubyte)((0.299*((double)r))+(0.587*((double)g)+0.114)*((double)b));
545 				*dstPtr=(ubyte)rgb_2_gray(*srcPtr,*(srcPtr+1),*(srcPtr+2));
546 			}
547 		}
548 		dstNumComponents=1;
549 		// sourceColorSpace=grayScale; // We don't want to change this, as we are only changing the
550 		// current strip.
551 	}
552 	else
553 		assert(1);
554 
555 	//writeOutputFile(stripWidth*stripHeight, strip, m_pPCLmSSettings->user_name);
556 	return(true);
557 }
558 
injectRLEStrip(ubyte * RLEBuffer,int numBytes,int imageWidth,int imageHeight,colorSpaceDisposition destColorSpace,bool whiteStrip)559 int PCLmGenerator::injectRLEStrip(ubyte *RLEBuffer, int numBytes, int imageWidth, int imageHeight, colorSpaceDisposition destColorSpace, bool whiteStrip)
560 {
561 	//unsigned char c;
562 	int strLength;
563 	char str[512];
564 	char fileStr[25];
565 	static int stripCount=0;
566 
567 	if(DebugIt2)
568 	{
569 		dbglog("Injecting RLE compression stream into PDF\n");
570 		dbglog("  numBytes=%d, imageWidth=%d, imageHeight=%d\n",numBytes,imageWidth,imageHeight);
571 
572 		snprintf(fileStr,25,"rleFile.%d",stripCount);
573 		stripCount++;
574 		write2Buff(RLEBuffer,numBytes);
575 	}
576 
577 	if(destColorSpace==adobeRGB)
578 	{
579 		injectAdobeRGBCS();
580 	}
581 
582 	// Inject LZ compressed image into PDF file
583 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Strip Stream: RLE Image \n"); writeStr2OutBuff(pOutStr);
584 	statOutputFileSize();
585 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
586 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
587 	snprintf(pOutStr,OUT_STR_SIZE,"/Width %d\n", imageWidth); writeStr2OutBuff(pOutStr);
588 	if(destColorSpace==deviceRGB)
589 	{
590 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
591 	}
592 	else if(destColorSpace==adobeRGB)
593 	{
594 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace 5 0 R\n"); writeStr2OutBuff(pOutStr);
595 	}
596 	else if(destColorSpace==blackonly)
597 	{
598 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
599 	}
600 	else
601 	{
602 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceGray\n"); writeStr2OutBuff(pOutStr);
603 	}
604 	snprintf(pOutStr,OUT_STR_SIZE,"/Height %d\n", imageHeight); writeStr2OutBuff(pOutStr);
605 	snprintf(pOutStr,OUT_STR_SIZE,"/Filter /RunLengthDecode\n"); writeStr2OutBuff(pOutStr);
606 	snprintf(pOutStr,OUT_STR_SIZE,"/Subtype /Image\n"); writeStr2OutBuff(pOutStr);
607 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",numBytes); writeStr2OutBuff(pOutStr);
608 	snprintf(pOutStr,OUT_STR_SIZE,"/Type /XObject\n"); writeStr2OutBuff(pOutStr);
609 	snprintf(pOutStr,OUT_STR_SIZE,"/BitsPerComponent 8\n"); writeStr2OutBuff(pOutStr);
610 #ifdef SUPPORT_WHITE_STRIPS
611 	if(whiteStrip)
612 	{
613 		snprintf(pOutStr,OUT_STR_SIZE,"/Name /WhiteStrip\n"); writeStr2OutBuff(pOutStr);
614 	}
615 	else
616 	{
617 		snprintf(pOutStr,OUT_STR_SIZE,"/Name /ColorStrip\n"); writeStr2OutBuff(pOutStr);
618 	}
619 #endif
620 
621 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
622 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
623 
624 	// Write the zlib compressed strip to the PDF output file
625 	write2Buff(RLEBuffer,numBytes);
626 	snprintf(pOutStr,OUT_STR_SIZE,"\nendstream\n"); writeStr2OutBuff(pOutStr);
627 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
628 
629 	// Output image transformation information
630 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: Object - Image Transformation \n"); writeStr2OutBuff(pOutStr);
631 	statOutputFileSize();
632 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
633 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
634 
635 	snprintf(str,512,"q /image Do Q\n");
636 	strLength=strlen(str);
637 
638 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",strLength); writeStr2OutBuff(pOutStr);
639 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
640 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
641 	snprintf(pOutStr,OUT_STR_SIZE,"%s",str); writeStr2OutBuff(pOutStr);
642 	snprintf(pOutStr,OUT_STR_SIZE,"endstream\n"); writeStr2OutBuff(pOutStr);
643 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
644 
645 	return(1);
646 }
647 
injectLZStrip(ubyte * LZBuffer,int numBytes,int imageWidth,int imageHeight,colorSpaceDisposition destColorSpace,bool whiteStrip)648 int PCLmGenerator::injectLZStrip(ubyte *LZBuffer, int numBytes, int imageWidth, int imageHeight, colorSpaceDisposition destColorSpace, bool whiteStrip)
649 {
650 	//unsigned char c;
651 	int strLength;
652 	char str[512];
653 
654 	if(DebugIt2)
655 	{
656 		dbglog("Injecting LZ compression stream into PDF\n");
657 		dbglog("  numBytes=%d, imageWidth=%d, imageHeight=%d\n",numBytes,imageWidth,imageHeight);
658 	}
659 
660 	if(destColorSpace==adobeRGB)
661 	{
662 		injectAdobeRGBCS();
663 	}
664 
665 	// Inject LZ compressed image into PDF file
666 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Strip Stream: zlib Image \n"); writeStr2OutBuff(pOutStr);
667 	statOutputFileSize();
668 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
669 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
670 	snprintf(pOutStr,OUT_STR_SIZE,"/Width %d\n", imageWidth); writeStr2OutBuff(pOutStr);
671 	if(destColorSpace==deviceRGB)
672 	{
673 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
674 	}
675 	else if(destColorSpace==adobeRGB)
676 	{
677 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace 5 0 R\n"); writeStr2OutBuff(pOutStr);
678 	}
679 	else if(destColorSpace==blackonly)
680 	{
681 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
682 	}
683 	else
684 	{
685 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceGray\n"); writeStr2OutBuff(pOutStr);
686 	}
687 	snprintf(pOutStr,OUT_STR_SIZE,"/Height %d\n", imageHeight); writeStr2OutBuff(pOutStr);
688 	snprintf(pOutStr,OUT_STR_SIZE,"/Filter /FlateDecode\n"); writeStr2OutBuff(pOutStr);
689 	snprintf(pOutStr,OUT_STR_SIZE,"/Subtype /Image\n"); writeStr2OutBuff(pOutStr);
690 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",numBytes); writeStr2OutBuff(pOutStr);
691 	snprintf(pOutStr,OUT_STR_SIZE,"/Type /XObject\n"); writeStr2OutBuff(pOutStr);
692 	snprintf(pOutStr,OUT_STR_SIZE,"/BitsPerComponent 8\n"); writeStr2OutBuff(pOutStr);
693 #ifdef SUPPORT_WHITE_STRIPS
694 	if(whiteStrip)
695 	{
696 		snprintf(pOutStr,OUT_STR_SIZE,"/Name /WhiteStrip\n"); writeStr2OutBuff(pOutStr);
697 	}
698 	else
699 	{
700 		snprintf(pOutStr,OUT_STR_SIZE,"/Name /ColorStrip\n"); writeStr2OutBuff(pOutStr);
701 	}
702 #endif
703 
704 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
705 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
706 
707 	// Write the zlib compressed strip to the PDF output file
708 	write2Buff(LZBuffer,numBytes);
709 	snprintf(pOutStr,OUT_STR_SIZE,"\nendstream\n"); writeStr2OutBuff(pOutStr);
710 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
711 
712 	// Output image transformation information
713 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: Object - Image Transformation \n"); writeStr2OutBuff(pOutStr);
714 	statOutputFileSize();
715 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
716 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
717 
718 	snprintf(str,512,"q /image Do Q\n");
719 	strLength=strlen(str);
720 
721 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",strLength); writeStr2OutBuff(pOutStr);
722 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
723 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
724 	snprintf(pOutStr,OUT_STR_SIZE,"%s",str); writeStr2OutBuff(pOutStr);
725 	snprintf(pOutStr,OUT_STR_SIZE,"endstream\n"); writeStr2OutBuff(pOutStr);
726 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
727 
728 	return(1);
729 }
730 
injectJPEG(char * jpeg_Buff,int imageWidth,int imageHeight,int numCompBytes,colorSpaceDisposition destColorSpace,bool whiteStrip)731 int PCLmGenerator::injectJPEG(char *jpeg_Buff, int imageWidth, int imageHeight, int numCompBytes, colorSpaceDisposition destColorSpace, bool whiteStrip)
732 {
733 	// int fd, bytesRead;
734 	int strLength;
735 	char str[512];
736 
737 	if(DebugIt2)
738 	{
739 		dbglog("Injecting jpegBuff into PDF\n");
740 	}
741 
742 	yPosition+=imageHeight;
743 
744 	if(destColorSpace==adobeRGB)
745 	{
746 		injectAdobeRGBCS();
747 	}
748 
749 	// Inject PDF JPEG into output file
750 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Strip Stream: jpeg Image \n"); writeStr2OutBuff(pOutStr);
751 	statOutputFileSize();
752 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
753 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
754 	snprintf(pOutStr,OUT_STR_SIZE,"/Width %d\n", imageWidth); writeStr2OutBuff(pOutStr);
755 	if(destColorSpace==deviceRGB)
756 	{
757 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
758 	}
759 	else if(destColorSpace==adobeRGB)
760 	{
761 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace 5 0 R\n"); writeStr2OutBuff(pOutStr);
762 	}
763 	else if(destColorSpace==blackonly)
764 	{
765 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceRGB\n"); writeStr2OutBuff(pOutStr);
766 	}
767 	else
768 	{
769 		snprintf(pOutStr,OUT_STR_SIZE,"/ColorSpace /DeviceGray\n"); writeStr2OutBuff(pOutStr);
770 	}
771 	snprintf(pOutStr,OUT_STR_SIZE,"/Height %d\n", imageHeight); writeStr2OutBuff(pOutStr);
772 	snprintf(pOutStr,OUT_STR_SIZE,"/Filter /DCTDecode\n"); writeStr2OutBuff(pOutStr);
773 	snprintf(pOutStr,OUT_STR_SIZE,"/Subtype /Image\n"); writeStr2OutBuff(pOutStr);
774 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",numCompBytes); writeStr2OutBuff(pOutStr);
775 	snprintf(pOutStr,OUT_STR_SIZE,"/Type /XObject\n"); writeStr2OutBuff(pOutStr);
776 	snprintf(pOutStr,OUT_STR_SIZE,"/BitsPerComponent 8\n"); writeStr2OutBuff(pOutStr);
777 #ifdef SUPPORT_WHITE_STRIPS
778 	if(whiteStrip)
779 	{
780 		snprintf(pOutStr,OUT_STR_SIZE,"/Name /WhiteStrip\n"); writeStr2OutBuff(pOutStr);
781 	}
782 	else
783 	{
784 		snprintf(pOutStr,OUT_STR_SIZE,"/Name /ColorStrip\n"); writeStr2OutBuff(pOutStr);
785 	}
786 #endif
787 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
788 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
789 
790 	// Inject JPEG image into stream
791 	//fd = open(jpeg_filename, O_RDWR);
792 	//if(fd==-1)
793 	//{
794 	//  fprintf (stderr, "Could not open the image file %s.\n", jpeg_filename);
795 	//  exit(-1);
796 	//}
797 
798 	//inPtr=(unsigned char *)malloc(fileSize);
799 	//bytesRead=read(fd, inPtr, fileSize);
800 	//write(stdout, inPtr, bytesRead);
801 	write2Buff((ubyte*)jpeg_Buff,numCompBytes);
802 	snprintf(pOutStr,OUT_STR_SIZE,"\nendstream\n"); writeStr2OutBuff(pOutStr);
803 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
804 
805 	snprintf(str,512,"q /image Do Q\n");
806 	strLength=strlen(str);
807 
808 	// Output image transformation information
809 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: Object - Image Transformation \n"); writeStr2OutBuff(pOutStr);
810 	statOutputFileSize();
811 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); objCounter++; writeStr2OutBuff(pOutStr);
812 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
813 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",strLength); writeStr2OutBuff(pOutStr);
814 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
815 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
816 	snprintf(pOutStr,OUT_STR_SIZE,"%s",str); writeStr2OutBuff(pOutStr);
817 	snprintf(pOutStr,OUT_STR_SIZE,"endstream\n"); writeStr2OutBuff(pOutStr);
818 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
819 
820 	return(1);
821 }
822 
823 
writeStr2Buff(char * buffer,char * str)824 void writeStr2Buff(char *buffer,char *str)
825 {
826 	int buffSize;
827 	char *buffPos;
828 
829 	buffSize=strlen(buffer)+strlen(str);
830 	if(buffSize>TEMP_BUFF_SIZE)
831 		assert(0);
832 
833 	buffSize=strlen(buffer);
834 	buffPos=buffer+buffSize;
835 	snprintf(buffPos,TEMP_BUFF_SIZE - buffSize,"%s",str);
836 
837 	buffSize=strlen(buffer);
838 	if(buffSize>TEMP_BUFF_SIZE)
839 	{
840 		dbglog("tempBuff size exceeded: buffSize=%d\n",buffSize);
841 		assert(0);
842 	}
843 }
844 
845 
846 /**********************************************************************************************
847 * Function:       writePDFGrammarPage
848 * Purpose:        to generate the PDF page construct(s), which includes the image information.
849 * Implementation: the /Length definition is required for PDF, so we write the stream to a RAM buffer
850 *      first, then calculate the Buffer size, insert the PDF /Length construct, then write the
851 *      buffer to the PDF file.  I used the RAM buffer instead of a temporary file, as a driver
852 *      implementation won't be able to use a disk file.
853 ***********************************************************************************************/
854 
writePDFGrammarPage(int imageWidth,int imageHeight,int numStrips,colorSpaceDisposition destColorSpace)855 void PCLmGenerator::writePDFGrammarPage(int imageWidth, int imageHeight, int numStrips, colorSpaceDisposition destColorSpace)
856 {
857 	int i, imageRef=objCounter+2, buffSize;
858 	int yAnchor;
859 	char str[512];
860 	char *tempBuffer = NULL;
861 	int startImageIndex=0;
862 	int numLinesLeft = 0;
863 
864 	if(destColorSpace==adobeRGB && 1 == pageCount)
865 	{
866 		imageRef+=2; // Add 2 for AdobeRGB
867 	}
868 
869 	tempBuffer=(char *)malloc(TEMP_BUFF_SIZE);
870 	assert(tempBuffer);
871 
872 	if (NULL == tempBuffer)/*Fix for Coverity CID: 63764*/
873 	{
874 		return;
875 	}
876 	if(DebugIt2)
877 		dbglog("Allocated %d bytes for tempBuffer\n",TEMP_BUFF_SIZE);
878 	memset(tempBuffer,0x0,TEMP_BUFF_SIZE);
879 
880 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Object 3 - page object\n"); writeStr2OutBuff(pOutStr);
881 	statOutputFileSize();
882 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n", objCounter); writeStr2OutBuff(pOutStr);
883 	addKids(objCounter);
884 	objCounter++;
885 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
886 	snprintf(pOutStr,OUT_STR_SIZE,"/Type /Page\n"); writeStr2OutBuff(pOutStr);
887 	snprintf(pOutStr,OUT_STR_SIZE,"/Parent %d 0 R\n",PAGES_OBJ_NUMBER); writeStr2OutBuff(pOutStr);
888 	snprintf(pOutStr,OUT_STR_SIZE,"/Resources <<\n"); writeStr2OutBuff(pOutStr);
889 	// snprintf(pOutStr,OUT_STR_SIZE,"/ProcSet [ /PDF /ImageC ]\n"); writeStr2OutBuff(pOutStr);
890 	snprintf(pOutStr,OUT_STR_SIZE,"/XObject <<\n"); writeStr2OutBuff(pOutStr);
891 
892 	if(topMarginInPix)
893 	{
894 		for(i=0;i<numFullInjectedStrips;i++,startImageIndex++)
895 		{
896 			snprintf(str,512,"/Image%d %d 0 R\n",startImageIndex,imageRef);
897 			snprintf(pOutStr,OUT_STR_SIZE,"%s",str); writeStr2OutBuff(pOutStr);
898 			imageRef+=2;
899 		}
900 		if(numPartialScanlinesToInject)
901 		{
902 			snprintf(str,512,"/Image%d %d 0 R\n",startImageIndex,imageRef);
903 			snprintf(pOutStr,OUT_STR_SIZE,"%s",str); writeStr2OutBuff(pOutStr);
904 			imageRef+=2;
905 			startImageIndex++;
906 		}
907 	}
908 
909 	for(i=startImageIndex;i<numStrips+startImageIndex;i++)
910 	{
911 		snprintf(str,512,"/Image%d %d 0 R\n",i,imageRef);
912 		// snprintf(pOutStr,OUT_STR_SIZE,"/ImageA 4 0 R /ImageB 6 0 R >>\n"); writeStr2OutBuff(pOutStr);
913 		snprintf(pOutStr,OUT_STR_SIZE,"%s",str); writeStr2OutBuff(pOutStr);
914 		imageRef+=2;
915 	}
916 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
917 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
918 	if(currMediaOrientationDisposition==landscapeOrientation)
919 	{
920 		pageOrigin=mediaWidth;
921 		snprintf(pOutStr,OUT_STR_SIZE,"/MediaBox [ 0 0 %d %d ]\n", mediaHeight, mediaWidth); writeStr2OutBuff(pOutStr);
922 	}
923 	else
924 	{
925 		pageOrigin=mediaHeight;
926 		snprintf(pOutStr,OUT_STR_SIZE,"/MediaBox [ 0 0 %d %d ]\n", mediaWidth, mediaHeight); writeStr2OutBuff(pOutStr);
927 	}
928 	snprintf(pOutStr,OUT_STR_SIZE,"/Contents [ %d 0 R ]\n",objCounter); writeStr2OutBuff(pOutStr);
929 #ifdef PIECEINFO_SUPPORTED
930 	snprintf(pOutStr,OUT_STR_SIZE,"/PieceInfo <</HPAddition %d 0 R >> \n",9997); writeStr2OutBuff(pOutStr);
931 #endif
932 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
933 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
934 
935 	// Create the FileBody stream first, so we know the Length of the stream
936 	if(reverseOrder)
937 	{
938 		yAnchor=0;
939 	}
940 	else
941 	{
942 		yAnchor=(int)((pageOrigin*STANDARD_SCALE)+0.99); // Round up
943 	}
944 
945 	// Setup the CTM so that we can send device-resolution coordinates
946 	snprintf(pOutStr,OUT_STR_SIZE,"%%Image Transformation Matrix: width, skewX, skewY, height, xAnchor, yAnchor\n"); writeStr2OutBuff(pOutStr);
947 	snprintf(str,512,"%f 0 0 %f 0 0 cm\n",STANDARD_SCALE_FOR_PDF/currRenderResolutionInteger,STANDARD_SCALE_FOR_PDF/currRenderResolutionInteger);
948 	writeStr2Buff(tempBuffer,str);
949 
950 	startImageIndex=0;
951 	if(topMarginInPix)
952 	{
953 		for(i=0;i<numFullInjectedStrips;i++)
954 		{
955 			if(reverseOrder)
956 				yAnchor+=numFullScanlinesToInject;
957 			else
958 				yAnchor-=numFullScanlinesToInject;
959 
960 			snprintf(str,512,"/P <</MCID 0>> BDC q\n");
961 			writeStr2Buff(tempBuffer,str);
962 
963 			snprintf(str,512,"%%Image Transformation Matrix: width, skewX, skewY, height, xAnchor, yAnchor\n");
964 			writeStr2Buff(tempBuffer,str);
965 
966 			snprintf(str,512,"%d 0 0 %d 0 %d cm\n",imageWidth*scaleFactor,numFullScanlinesToInject*scaleFactor,yAnchor*scaleFactor);
967 			writeStr2Buff(tempBuffer,str);
968 
969 			snprintf(str,512,"/Image%d Do Q\n",startImageIndex);
970 			writeStr2Buff(tempBuffer,str);
971 
972 			startImageIndex++;
973 		}
974 		if(numPartialScanlinesToInject)
975 		{
976 			if(reverseOrder)
977 				yAnchor+=numPartialScanlinesToInject;
978 			else
979 				yAnchor-=numPartialScanlinesToInject;
980 
981 			snprintf(str,512,"/P <</MCID 0>> BDC q\n");
982 			writeStr2Buff(tempBuffer,str);
983 
984 			snprintf(str,512,"%%Image Transformation Matrix: width, skewX, skewY, height, xAnchor, yAnchor\n");
985 			writeStr2Buff(tempBuffer,str);
986 
987 			snprintf(str,512,"%d 0 0 %d 0 %d cm\n",imageWidth*scaleFactor,numPartialScanlinesToInject*scaleFactor,yAnchor*scaleFactor);
988 			writeStr2Buff(tempBuffer,str);
989 
990 			snprintf(str,512,"/Image%d Do Q\n",startImageIndex);
991 			writeStr2Buff(tempBuffer,str);
992 
993 			startImageIndex++;
994 		}
995 	}
996 
997 	for(i=startImageIndex;i<numStrips+startImageIndex;i++)
998 	{
999 		//last strip may have less lines than currStripHeight. So update yAnchor using left over lines
1000 		if(i == (numStrips+startImageIndex-1))
1001 		{
1002 			numLinesLeft = currSourceHeight - ((numStrips-1) * currStripHeight);
1003 
1004 			if(reverseOrder)
1005 				yAnchor+=numLinesLeft;
1006 			else
1007 				yAnchor-=numLinesLeft;
1008 		}
1009 		else
1010 		{
1011 			if(reverseOrder)
1012 				yAnchor+=currStripHeight;
1013 			else
1014 				yAnchor-=currStripHeight;
1015 		}
1016 
1017 		snprintf(str,512,"/P <</MCID 0>> BDC q\n");
1018 		writeStr2Buff(tempBuffer,str);
1019 
1020 		snprintf(str,512,"%%Image Transformation Matrix: width, skewX, skewY, height, xAnchor, yAnchor\n");
1021 		writeStr2Buff(tempBuffer,str);
1022 
1023 		if(i == (numStrips+startImageIndex-1)) //last strip may have less lines than currStripHeight
1024 		{
1025 			snprintf(str,512,"%d 0 0 %d 0 %d cm\n",imageWidth*scaleFactor,numLinesLeft*scaleFactor,yAnchor*scaleFactor);
1026 			writeStr2Buff(tempBuffer,str);
1027 		}
1028 		else if(yAnchor<0)
1029 		{
1030 			sint32 newH=currStripHeight+yAnchor;
1031 			snprintf(str,512,"%d 0 0 %d 0 %d cm\n",imageWidth*scaleFactor,newH*scaleFactor,0*scaleFactor);
1032 			writeStr2Buff(tempBuffer,str);
1033 		}
1034 		else
1035 		{
1036 			snprintf(str,512,"%d 0 0 %d 0 %d cm\n",imageWidth*scaleFactor,currStripHeight*scaleFactor,yAnchor*scaleFactor);
1037 			writeStr2Buff(tempBuffer,str);
1038 		}
1039 
1040 		snprintf(str,512,"/Image%d Do Q\n",i);
1041 		writeStr2Buff(tempBuffer,str);
1042 
1043 	}
1044 
1045 	// Resulting buffer size
1046 	buffSize=strlen(tempBuffer);
1047 
1048 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: FileBody: Page Content Stream object\n"); writeStr2OutBuff(pOutStr);
1049 	statOutputFileSize();
1050 	snprintf(pOutStr,OUT_STR_SIZE,"%d 0 obj\n",objCounter); writeStr2OutBuff(pOutStr);
1051 	snprintf(pOutStr,OUT_STR_SIZE,"<<\n"); writeStr2OutBuff(pOutStr);
1052 
1053 	snprintf(pOutStr,OUT_STR_SIZE,"/Length %d\n",buffSize); writeStr2OutBuff(pOutStr);
1054 	snprintf(pOutStr,OUT_STR_SIZE,">>\n"); writeStr2OutBuff(pOutStr);
1055 	snprintf(pOutStr,OUT_STR_SIZE,"stream\n"); writeStr2OutBuff(pOutStr);
1056 
1057 	// Now write the FileBody stream
1058 	write2Buff((ubyte*)tempBuffer,buffSize);
1059 
1060 	snprintf(pOutStr,OUT_STR_SIZE,"endstream\n"); writeStr2OutBuff(pOutStr);
1061 	snprintf(pOutStr,OUT_STR_SIZE,"endobj\n"); writeStr2OutBuff(pOutStr);
1062 	objCounter++;
1063 	if(tempBuffer)
1064 	{
1065 		free(tempBuffer);
1066 		tempBuffer=NULL;
1067 	}
1068 }
1069 
1070 
1071 /****************************************************************************************
1072 * Function: prepImageForBacksideDuplex
1073 * Purpose:  To mirror the source image in preperation for backside duplex support
1074 * Limitations:
1075 *   -
1076 *****************************************************************************************/
prepImageForBacksideDuplex(ubyte * imagePtr,sint32 imageHeight,sint32 imageWidth,sint32 numComponents)1077 boolean prepImageForBacksideDuplex(ubyte *imagePtr, sint32 imageHeight, sint32 imageWidth, sint32 numComponents)
1078 {
1079 	sint32 numBytes=imageHeight*imageWidth*numComponents;
1080 	ubyte *head, *tail, t0, t1, t2;
1081 
1082 	if(numComponents==3)
1083 	{
1084 		for(head=imagePtr,tail=imagePtr+numBytes-1;tail>head;)
1085 		{
1086 			t0=*head;
1087 			t1=*(head+1);
1088 			t2=*(head+2);
1089 
1090 			*head=    *(tail-2);
1091 			*(head+1)=*(tail-1);
1092 			*(head+2)=*(tail-0);
1093 			*tail=    t2;
1094 			*(tail-1)=t1;
1095 			*(tail-2)=t0;
1096 
1097 			head+=3;
1098 			tail-=3;
1099 		}
1100 	}
1101 	else
1102 	{
1103 		for(head=imagePtr,tail=imagePtr+numBytes;tail>head;)
1104 		{
1105 			t0=*head;
1106 			*head=*tail;
1107 			*tail=t0;
1108 			head++;
1109 			tail--;
1110 		}
1111 	}
1112 	//origTail++;
1113 	return(TRUE);
1114 }
1115 
getInputBinString(jobInputBin bin)1116 char* PCLmGenerator::getInputBinString(jobInputBin bin)
1117 {
1118 	memset(returnStr,0,sizeof(returnStr));
1119 	switch (bin)
1120 	{
1121 	case alternate:      strncpy(returnStr,"alternate", sizeof(returnStr)); break;
1122 	case alternate_roll: strncpy(returnStr,"alternate_roll", sizeof(returnStr)); break;
1123 	case auto_select:    strncpy(returnStr,"auto_select", sizeof(returnStr)); break;
1124 	case bottom:         strncpy(returnStr,"bottom", sizeof(returnStr)); break;
1125 	case center:         strncpy(returnStr,"center", sizeof(returnStr)); break;
1126 	case disc:           strncpy(returnStr,"disc", sizeof(returnStr)); break;
1127 	case envelope:       strncpy(returnStr,"envelope", sizeof(returnStr)); break;
1128 	case hagaki:         strncpy(returnStr,"hagaki", sizeof(returnStr)); break;
1129 	case large_capacity: strncpy(returnStr,"large_capacity", sizeof(returnStr)); break;
1130 	case left:           strncpy(returnStr,"left", sizeof(returnStr)); break;
1131 	case main_tray:      strncpy(returnStr,"main_tray", sizeof(returnStr)); break;
1132 	case main_roll:      strncpy(returnStr,"main_roll", sizeof(returnStr)); break;
1133 	case manual:         strncpy(returnStr,"manual", sizeof(returnStr)); break;
1134 	case middle:         strncpy(returnStr,"middle", sizeof(returnStr)); break;
1135 	case photo:          strncpy(returnStr,"photo", sizeof(returnStr)); break;
1136 	case rear:           strncpy(returnStr,"rear", sizeof(returnStr)); break;
1137 	case right:          strncpy(returnStr,"right", sizeof(returnStr)); break;
1138 	case side:           strncpy(returnStr,"side", sizeof(returnStr)); break;
1139 	case top:            strncpy(returnStr,"top", sizeof(returnStr)); break;
1140 	case tray_1:         strncpy(returnStr,"tray_1", sizeof(returnStr)); break;
1141 	case tray_2:         strncpy(returnStr,"tray_2", sizeof(returnStr)); break;
1142 	case tray_3:         strncpy(returnStr,"tray_3", sizeof(returnStr)); break;
1143 	case tray_4:         strncpy(returnStr,"tray_4", sizeof(returnStr)); break;
1144 	case tray_5:         strncpy(returnStr,"tray_5", sizeof(returnStr)); break;
1145 	case tray_N:         strncpy(returnStr,"tray_N", sizeof(returnStr)); break;
1146 	default:			 strncpy(returnStr,"auto_select", sizeof(returnStr));  break; /*Use Auto for wrong option*/
1147 	}
1148 	return(returnStr);
1149 }
1150 
getOutputBin(jobOutputBin bin)1151 char* PCLmGenerator::getOutputBin(jobOutputBin bin)
1152 {
1153 	memset(returnStr,0,sizeof(returnStr));
1154 	switch(bin)
1155 	{
1156 	case top_output:               strncpy(returnStr,"top_output", sizeof(returnStr)); break;
1157 	case middle_output:            strncpy(returnStr,"middle_output", sizeof(returnStr)); break;
1158 	case bottom_output:            strncpy(returnStr,"bottom_output", sizeof(returnStr)); break;
1159 	case side_output:              strncpy(returnStr,"side_output", sizeof(returnStr)); break;
1160 	case center_output:            strncpy(returnStr,"center_output", sizeof(returnStr)); break;
1161 	case rear_output:              strncpy(returnStr,"rear_output", sizeof(returnStr)); break;
1162 	case face_up:                  strncpy(returnStr,"face_up", sizeof(returnStr)); break;
1163 	case face_down:                strncpy(returnStr,"face_down", sizeof(returnStr)); break;
1164 	case large_capacity_output:    strncpy(returnStr,"large_capacity_output", sizeof(returnStr)); break;
1165 	case stacker_N:                strncpy(returnStr,"stacker_N", sizeof(returnStr)); break;
1166 	case mailbox_N:                strncpy(returnStr,"mailbox_N", sizeof(returnStr)); break;
1167 	case tray_1_output:            strncpy(returnStr,"tray_1_output", sizeof(returnStr)); break;
1168 	case tray_2_output:            strncpy(returnStr,"tray_2_output", sizeof(returnStr)); break;
1169 	case tray_3_output:            strncpy(returnStr,"tray_3_output", sizeof(returnStr)); break;
1170 	case tray_4_output:            strncpy(returnStr,"tray_4_output", sizeof(returnStr)); break;
1171 	default:					   strncpy(returnStr,"top_output", sizeof(returnStr));  break;/*Use top for wrong option*/
1172 	}
1173 	return(returnStr);
1174 }
getOrientationString(mediaOrientationDisposition Orientation)1175 char* PCLmGenerator::getOrientationString(mediaOrientationDisposition Orientation)
1176 {
1177 	memset(returnStr,0,sizeof(returnStr));
1178 	switch (Orientation)
1179 	{
1180 	case portraitOrientation:
1181 		strncpy(returnStr,"portrait",sizeof(returnStr));
1182 		break;
1183 
1184 	case landscapeOrientation:
1185 		strncpy(returnStr,"landscape",sizeof(returnStr));
1186 		break;
1187 
1188 	default:
1189 		assert(0);
1190 		break;
1191 	}
1192 	return(returnStr);
1193 }
getDuplexString(duplexDispositionEnum duplex)1194 char* PCLmGenerator::getDuplexString(duplexDispositionEnum duplex)
1195 {
1196 	memset(returnStr,0,sizeof(returnStr));
1197 	switch (duplex)
1198 	{
1199 	case simplex:
1200 		strncpy(returnStr,"one-sided",sizeof(returnStr));
1201 		break;
1202 	case duplex_shortEdge:
1203 		strncpy(returnStr,"two-sided-short-edge",sizeof(returnStr));
1204 		break;
1205 
1206 	case duplex_longEdge:
1207 		strncpy(returnStr,"two-sided-long-edge",sizeof(returnStr));
1208 		break;
1209 
1210 	default:
1211 		assert(0);
1212 		break;
1213 	}
1214 	return(returnStr);
1215 }
1216 
getColorThemesString(colorThemes colortheme)1217 char* PCLmGenerator::getColorThemesString(colorThemes colortheme)
1218 {
1219     memset(returnStr,0,sizeof(returnStr));
1220     switch(colortheme)
1221     {
1222         case default_colortheme:  strncpy(returnStr,"auto",sizeof(returnStr));break;
1223         case vividsRGB:           strncpy(returnStr,"saturation",sizeof(returnStr));break;
1224         case photosRGB:           strncpy(returnStr,"perception",sizeof(returnStr));break;
1225         case photoAdobeRGB:       strncpy(returnStr,"perception",sizeof(returnStr));break;
1226         default:                  strncpy(returnStr,"none",sizeof(returnStr));break;
1227     }
1228     return (returnStr);
1229 }
1230 
1231 
writeJobTicket()1232 void PCLmGenerator::writeJobTicket()
1233 {
1234 	// Write JobTicket
1235 	char inputBin[256];
1236 	char outputBin[256];
1237 	char orientation[256];
1238 	char duplex[256];
1239 	char colorthemes[256];
1240 	strncpy(colorthemes,getColorThemesString(m_pPCLmSSettings->colorTheme),256);
1241 	strncpy(inputBin,getInputBinString(m_pPCLmSSettings->userInputBin),256);
1242 	strncpy(outputBin,getOutputBin(m_pPCLmSSettings->userOutputBin),256);
1243 	strncpy(orientation,getOrientationString(m_pPCLmSSettings->userOrientation),256);
1244 	strncpy(duplex,getDuplexString(currDuplexDisposition),256);
1245 
1246 	snprintf(pOutStr,OUT_STR_SIZE,"%%  genPCLm (Ver: %f)\n",PCLM_Ver); writeStr2OutBuff(pOutStr);
1247 	snprintf(pOutStr,OUT_STR_SIZE,"%%============= Job Ticket =============\n"); writeStr2OutBuff(pOutStr);
1248 	snprintf(pOutStr,OUT_STR_SIZE,"%%  PCLmS-Job-Ticket\n"); writeStr2OutBuff(pOutStr);
1249 	snprintf(pOutStr,OUT_STR_SIZE,"%%      job-ticket-version: 0.1\n"); writeStr2OutBuff(pOutStr);
1250 	snprintf(pOutStr,OUT_STR_SIZE,"%%      epcl-version: 1.01\n"); writeStr2OutBuff(pOutStr);
1251 	snprintf(pOutStr,OUT_STR_SIZE,"%%    JobSection\n"); writeStr2OutBuff(pOutStr);
1252 	snprintf(pOutStr,OUT_STR_SIZE,"%%      job-id: %d\n",m_pPCLmSSettings->jobid); writeStr2OutBuff(pOutStr);
1253 	snprintf(pOutStr,OUT_STR_SIZE,"%%      job-start-time: %s\n",m_pPCLmSSettings->datetime); writeStr2OutBuff(pOutStr);
1254 	snprintf(pOutStr,OUT_STR_SIZE,"%%    MediaHandlingSection\n"); writeStr2OutBuff(pOutStr);
1255 	snprintf(pOutStr,OUT_STR_SIZE,"%%      media-size-name: %s\n",currMediaName); writeStr2OutBuff(pOutStr);
1256 	snprintf(pOutStr,OUT_STR_SIZE,"%%      media-type: %s\n",m_pPCLmSSettings->userMediaType); writeStr2OutBuff(pOutStr);
1257 	snprintf(pOutStr,OUT_STR_SIZE,"%%      media-source: %s\n",inputBin); writeStr2OutBuff(pOutStr);
1258 	snprintf(pOutStr,OUT_STR_SIZE,"%%      sides: %s\n",duplex); writeStr2OutBuff(pOutStr);
1259 	//snprintf(pOutStr,OUT_STR_SIZE,"%%      finishings: xxx\n"); writeStr2OutBuff(pOutStr);
1260 	snprintf(pOutStr,OUT_STR_SIZE,"%%      output-bin: %s\n",outputBin); writeStr2OutBuff(pOutStr);
1261 	snprintf(pOutStr,OUT_STR_SIZE,"%%    RenderingSection\n"); writeStr2OutBuff(pOutStr);
1262 	if(currCompressionDisposition==compressDCT)
1263 	{
1264 		snprintf(pOutStr,OUT_STR_SIZE,"%%      pclm-compression-method: JPEG\n"); writeStr2OutBuff(pOutStr);
1265 	}
1266 	else if(currCompressionDisposition==compressFlate)
1267 	{
1268 		snprintf(pOutStr,OUT_STR_SIZE,"%%      pclm-compression-method: FLATE\n"); writeStr2OutBuff(pOutStr);
1269 	}
1270 	else
1271 	{
1272 		snprintf(pOutStr,OUT_STR_SIZE,"%%      pclm-compression-method: RLE\n"); writeStr2OutBuff(pOutStr);
1273 	}
1274 	snprintf(pOutStr,OUT_STR_SIZE,"%%      strip-height: %d\n",currStripHeight); writeStr2OutBuff(pOutStr);
1275 
1276 	if(destColorSpace==deviceRGB)
1277 	{
1278 		snprintf(pOutStr,OUT_STR_SIZE,"%%      print-color-mode: color\n"); writeStr2OutBuff(pOutStr);
1279 	}
1280 	else if(destColorSpace==adobeRGB)
1281 	{
1282 		snprintf(pOutStr,OUT_STR_SIZE,"%%      print-color-mode: color\n"); writeStr2OutBuff(pOutStr);
1283 	}
1284 	else if(destColorSpace==grayScale)
1285 	{
1286 		snprintf(pOutStr,OUT_STR_SIZE,"%%      print-color-mode: monochrome\n"); writeStr2OutBuff(pOutStr);
1287 	}
1288 	else if(destColorSpace==blackonly)
1289 	{
1290 		snprintf(pOutStr,OUT_STR_SIZE,"%%      print-color-mode: color\n"); writeStr2OutBuff(pOutStr);
1291 	}
1292 	snprintf(pOutStr,OUT_STR_SIZE,"%%      print-rendering-intent: %s\n",colorthemes); writeStr2OutBuff(pOutStr);
1293 	snprintf(pOutStr,OUT_STR_SIZE,"%%      print-quality: %s\n",m_pPCLmSSettings->userPageQuality); writeStr2OutBuff(pOutStr);
1294 	snprintf(pOutStr,OUT_STR_SIZE,"%%      printer-resolution: %d\n",currRenderResolutionInteger); writeStr2OutBuff(pOutStr);
1295 	//snprintf(pOutStr,OUT_STR_SIZE,"%%      print-content-optimized: xxx\n"); writeStr2OutBuff(pOutStr);
1296 	snprintf(pOutStr,OUT_STR_SIZE,"%%      orientation-requested: %d\n",m_pPCLmSSettings->userOrientation); writeStr2OutBuff(pOutStr);
1297 	snprintf(pOutStr,OUT_STR_SIZE,"%%      copies: %d\n",m_pPCLmSSettings->userCopies); writeStr2OutBuff(pOutStr);
1298 	snprintf(pOutStr,OUT_STR_SIZE,"%%      pclm-raster-back-side: xxx\n"); writeStr2OutBuff(pOutStr);
1299 	if(currRenderResolutionInteger)
1300 	{
1301 		snprintf(pOutStr,OUT_STR_SIZE,"%%      margins-pre-applied: TRUE\n"); writeStr2OutBuff(pOutStr);
1302 	}
1303 	else
1304 	{
1305 		snprintf(pOutStr,OUT_STR_SIZE,"%%      margins-pre-applied: FALSE\n"); writeStr2OutBuff(pOutStr);
1306 	}
1307 	snprintf(pOutStr,OUT_STR_SIZE,"%%  PCLmS-Job-Ticket-End\n"); writeStr2OutBuff(pOutStr);
1308 }
1309 
writePDFGrammarHeader()1310 void PCLmGenerator::writePDFGrammarHeader()
1311 {
1312 	// snprintf(pOutStr,OUT_STR_SIZE,"%%============= PCLm: File Header \n"); writeStr2OutBuff(pOutStr);
1313 	snprintf(pOutStr,OUT_STR_SIZE,"%%PDF-1.7\n"); writeStr2OutBuff(pOutStr);
1314 	snprintf(pOutStr,OUT_STR_SIZE,"%%PCLm 1.0\n"); writeStr2OutBuff(pOutStr);
1315 }
1316 
1317 /* PCLmGenerator Constructor
1318 *
1319 * /desc
1320 * /param
1321 * /return
1322 */
PCLmGenerator()1323 PCLmGenerator::PCLmGenerator()
1324 {
1325 	strncpy(currMediaName,"na_letter_8.5x11in",256);
1326 	currDuplexDisposition=simplex;
1327 	currColorSpaceDisposition=deviceRGB;
1328 	currDebugDisposition=debugOff;
1329 	currCompressionDisposition=compressDCT;
1330 	currMediaOrientationDisposition=portraitOrientation;
1331 	currRenderResolution=res600;
1332 	currStripHeight=STRIP_HEIGHT;
1333 
1334 	// Default media h/w to letter specification
1335 	mediaWidthInPixels=0;
1336 	mediaHeightInPixels=0;
1337 	mediaWidth=612;
1338 	mediaHeight=792;
1339 	destColorSpace=deviceRGB;
1340 	sourceColorSpace=deviceRGB;
1341 	scaleFactor=1;
1342 	genExtraPage=false;
1343 	jobOpen=job_closed;
1344 	currSourceWidth = 5100;
1345 	currSourceHeight = 6600;
1346 	srcNumComponents = 3;
1347 	dstNumComponents = 3;
1348 	numLeftoverScanlines = 0;
1349 	scratchBuffer=NULL;
1350 	pageCount=0;
1351 	reverseOrder = false;
1352 	outBuffSize = 0;
1353 	currOutBuffSize = 0;
1354 
1355 	currRenderResolutionInteger=600;
1356 	currResolution = 600;
1357 	STANDARD_SCALE=(float)currRenderResolutionInteger/(float)STANDARD_SCALE_FOR_PDF;
1358 	yPosition=0;
1359 	infoObj=0;
1360 	pageOrigin = 0;
1361 	numKids=0;
1362 	// XRefTable storage
1363 	xRefIndex=0;
1364 	xRefStart = 0;
1365 
1366 	DebugIt=0;
1367 	DebugIt2=0;
1368 
1369 	objCounter=PAGES_OBJ_NUMBER+1;
1370 	totalBytesWrittenToPCLmFile=0;
1371 	totalBytesWrittenToCurrBuff = 0;
1372 
1373 	// Initialize first index in xRefTable
1374 	xRefTable=NULL;
1375 	KidsArray=NULL;
1376 
1377 	// Initialize the output Buffer
1378 	allocatedOutputBuffer=NULL;
1379 
1380 	// Initialize the leftover scanline logic
1381 	leftoverScanlineBuffer=NULL;
1382 
1383 	adobeRGBCS_firstTime=true;
1384 	mirrorBackside=false;
1385 
1386 	topMarginInPix=0;
1387 	leftMarginInPix=0;
1388 
1389 	m_pPCLmSSettings = NULL;
1390 
1391 	outBuffPtr = NULL;
1392 	currBuffPtr = NULL;
1393 	memset(pOutStr,0,OUT_STR_SIZE);
1394 	firstStrip = true;
1395 	numFullInjectedStrips = 0;
1396 	numFullScanlinesToInject = 0;
1397 	numPartialScanlinesToInject = 0;
1398 	memset(returnStr,0,sizeof(returnStr));
1399 }
1400 
1401 /* PCLmGenerator Destructor
1402 *
1403 * /desc
1404 * /param
1405 * /return
1406 */
~PCLmGenerator()1407 PCLmGenerator::~PCLmGenerator()
1408 {
1409 	Cleanup();
1410 }
1411 
1412 /* StartJob
1413 *
1414 * /desc
1415 * /param
1416 * /return
1417 */
1418 #ifdef STANDALONE
StartJob(void ** pOutBuffer,int * iOutBufferSize,bool debug)1419 int  PCLmGenerator::StartJob(void **pOutBuffer, int *iOutBufferSize, bool debug)
1420 #else
1421 int  PCLmGenerator::StartJob(void **pOutBuffer, int *iOutBufferSize)
1422 #endif
1423 {
1424 	DebugIt=debug;
1425 	DebugIt2=debug;
1426 
1427 	if(DebugIt)
1428 		dbglog("genPCLm::StartJob\n");
1429 
1430 	// Allocate the output buffer; we don't know much at this point, so make the output buffer size
1431 	// the worst case dimensions; when we get a startPage, we will resize it appropriately
1432 	outBuffSize=DEFAULT_OUTBUFF_SIZE;
1433 	*iOutBufferSize=outBuffSize;
1434 	*pOutBuffer=(ubyte*)malloc(outBuffSize*10);
1435 
1436 	if(NULL == *pOutBuffer)
1437 	{
1438 		return(errorOutAndCleanUp());
1439 	}
1440 
1441 	currOutBuffSize=outBuffSize*10;
1442 	if(DebugIt2)
1443 	    	dbglog("Allocated %d for myOutBufferSize\n",outBuffSize);
1444 	allocatedOutputBuffer=*pOutBuffer;
1445 	initOutBuff((char*)*pOutBuffer,currOutBuffSize);
1446 	writePDFGrammarHeader();
1447 	*iOutBufferSize=totalBytesWrittenToCurrBuff;
1448 	jobOpen=job_open;
1449 
1450 	return(success);
1451 }
1452 
1453 /* EndJob
1454 *
1455 * /desc
1456 * /param
1457 * /return
1458 */
EndJob(void ** pOutBuffer,int * iOutBufferSize)1459 int  PCLmGenerator::EndJob(void **pOutBuffer, int *iOutBufferSize)
1460 {
1461 	//int result;
1462 
1463 	if(DebugIt)
1464     	dbglog("genPCLm::EndJob\n");
1465     if(NULL==allocatedOutputBuffer)
1466     {
1467       return(errorOutAndCleanUp());
1468     }
1469 	*pOutBuffer = allocatedOutputBuffer;
1470 
1471 	initOutBuff((char*)*pOutBuffer,outBuffSize);
1472 
1473 	// Write PDF trailer
1474 	writePDFGrammarTrailer(currSourceWidth, currSourceHeight);
1475 
1476 	/*if(!DebugIt && (currCompressionDisposition==compressDCT))
1477 	{
1478 		result=remove("jpeg_chunk.jpg");
1479 	}*/
1480 
1481 	*iOutBufferSize=totalBytesWrittenToCurrBuff;
1482 
1483 	jobOpen=job_closed;
1484 
1485 	if(xRefTable)
1486 	{
1487 		free(xRefTable);
1488 		xRefTable=NULL;
1489 	}
1490 	if(KidsArray)
1491 	{
1492 		free(KidsArray);
1493 		KidsArray=NULL;
1494 	}
1495 
1496 	return(success);
1497 }
1498 
1499 /* PCLmSStartPage
1500 *
1501 * /desc
1502 * /param
1503 * /return
1504 */
StartPage(PCLmSSetup * PCLmSPageContent,bool generatePCLmS,void ** pOutBuffer,int * iOutBufferSize)1505 int  PCLmGenerator::StartPage(PCLmSSetup *PCLmSPageContent, bool generatePCLmS, void **pOutBuffer, int *iOutBufferSize)
1506 {
1507 	m_pPCLmSSettings=PCLmSPageContent->PCLmSUserSettings;
1508 	return(StartPage(PCLmSPageContent->PCLmPageContent,pOutBuffer,iOutBufferSize));
1509 }
1510 
1511 /* StartPage
1512 *
1513 * /desc
1514 * /param
1515 * /return
1516 */
StartPage(PCLmPageSetup * PCLmPageContent,void ** pOutBuffer,int * iOutBufferSize)1517 int  PCLmGenerator::StartPage(PCLmPageSetup *PCLmPageContent, void **pOutBuffer, int *iOutBufferSize)
1518 {
1519 	int numImageStrips;
1520 	// Save the resolution information
1521 	currRenderResolution=PCLmPageContent->destinationResolution;
1522 
1523 	*pOutBuffer = allocatedOutputBuffer;
1524 
1525 	if(currRenderResolution==res300)
1526 		currRenderResolutionInteger=300;
1527 	else if(currRenderResolution==res600)
1528 		currRenderResolutionInteger=600;
1529 	else if(currRenderResolution==res1200)
1530 		currRenderResolutionInteger=1200;
1531 	else
1532 		assert(0);
1533 
1534 	// Recalculate STANDARD_SCALE to reflect the job resolution
1535 	STANDARD_SCALE=(float)currRenderResolutionInteger/(float)STANDARD_SCALE_FOR_PDF;
1536 
1537 	// Media and source sizes are in 72 DPI; convert media information to native resolutions:
1538 	//   Add 0.5 to force rounding
1539 	currSourceWidth=(int)(PCLmPageContent->sourceWidth+0.50);
1540 	currSourceHeight=(int)(PCLmPageContent->sourceHeight+0.50);
1541 
1542 	// Save off the media information
1543     mediaWidth=(int)(PCLmPageContent->mediaWidth + 0.50);
1544     mediaHeight=(int)(PCLmPageContent->mediaHeight + 0.50);
1545 	mediaWidthInPixels =(int)(((PCLmPageContent->mediaWidth/STANDARD_SCALE_FOR_PDF)*currRenderResolutionInteger)+0.50);
1546 	mediaHeightInPixels=(int)(((PCLmPageContent->mediaHeight/STANDARD_SCALE_FOR_PDF)*currRenderResolutionInteger)+0.50);
1547 	topMarginInPix=(int)(PCLmPageContent->mediaHeightOffset+0.50);
1548 	leftMarginInPix=(int)(PCLmPageContent->mediaWidthOffset+0.50);
1549 	currCompressionDisposition=PCLmPageContent->compTypeRequested;
1550 
1551 	if(DebugIt)
1552 	{
1553 		dbglog("genPCLm::StartPage\n");
1554 		dbglog("  mediaName=%s\n",   PCLmPageContent->mediaSizeName);
1555 		dbglog("  clientLocale=%s\n",PCLmPageContent->mediaSizeName);
1556 		dbglog("  mediaHeight=%f\n", PCLmPageContent->mediaHeight);
1557 		dbglog("  mediaWidth=%f\n",  PCLmPageContent->mediaWidth);
1558 		dbglog("  topMargin=%d\n",   topMarginInPix);
1559 		dbglog("  leftMargin=%d\n",  leftMarginInPix);
1560 
1561 		dbglog("  topLeftMargin=%f,%f\n",PCLmPageContent->mediaWidthOffset,PCLmPageContent->mediaHeightOffset);
1562 		dbglog("  sourceHeight=%f\n",PCLmPageContent->sourceHeight);
1563 		dbglog("  sourceWidth=%f\n", PCLmPageContent->sourceWidth);
1564 		dbglog("  stripHeight=%d\n", PCLmPageContent->stripHeight);
1565 		dbglog("  scaleFactor=%d\n", PCLmPageContent->scaleFactor);
1566 		dbglog("  genExtraPage=%d\n",PCLmPageContent->genExtraPage);
1567 
1568 		if(PCLmPageContent->colorContent==color_content){
1569 			dbglog("  colorContent=color_content\n");
1570 			}
1571         else if(PCLmPageContent->colorContent==gray_content){
1572             dbglog("  colorContent=gray_content\n");
1573             }
1574         else{
1575             dbglog("  colorContent=unknown_content\n");
1576             }
1577 
1578 		if(PCLmPageContent->pageOrigin==top_left){
1579 			dbglog("  pageOrigin=top_left\n");
1580 			}
1581 			else{
1582 			dbglog("  pageOrigin=bottom_right\n");
1583 			}
1584 		if(PCLmPageContent->compTypeRequested==compressRLE){
1585 			dbglog("compTypeRequested=RLE\n");
1586 			}
1587 		else if(PCLmPageContent->compTypeRequested==compressDCT){
1588 			dbglog("compTypeRequested=DCT\n");
1589 			}
1590 		else if(PCLmPageContent->compTypeRequested==compressFlate){
1591 			dbglog("compTypeRequested=Flate\n");
1592 			}
1593 		else if(PCLmPageContent->compTypeRequested==compressDefault){
1594 			dbglog("compTypeRequested=Flate\n");
1595 			}
1596 		else if(PCLmPageContent->compTypeRequested==compressNone){
1597 			dbglog("compTypeRequested=None\n");
1598 			}
1599 
1600 		if(PCLmPageContent->dstColorSpaceSpefication==deviceRGB){
1601 			dbglog("colorSpaceSpefication=deviceRGB\n");
1602 			}
1603 		else if(PCLmPageContent->dstColorSpaceSpefication==adobeRGB){
1604 			dbglog("colorSpaceSpefication=adobeRGB\n");
1605 			}
1606 		else if(PCLmPageContent->dstColorSpaceSpefication==grayScale){
1607 			dbglog("colorSpaceSpefication=grayScale\n");
1608 			}
1609         else{ //if blackonly
1610 			dbglog("colorSpaceSpefication=blackonly\n");
1611 			}
1612 
1613 
1614 		if(PCLmPageContent->destinationResolution==res300){
1615 			dbglog("destinationResolution Requested=300 DPI\n");
1616 			}
1617 		else if(PCLmPageContent->destinationResolution==res600){
1618 			dbglog("destinationResolution Requested=600 DPI\n");
1619 			}
1620 		else if(PCLmPageContent->destinationResolution==res1200){
1621 			dbglog("destinationResolution Requested=1200 DPI\n");
1622 			}
1623 
1624 		if(PCLmPageContent->duplexDisposition==simplex){
1625 			dbglog("duplex disposition=Simplex\n");
1626 			}
1627 		else if(PCLmPageContent->duplexDisposition==duplex_longEdge){
1628 			dbglog("duplex disposition=Duplex_longEdge\n");
1629 			}
1630 		else if(PCLmPageContent->duplexDisposition==duplex_shortEdge){
1631 			dbglog("duplex disposition=Duplex_shortEdge\n");
1632 			}
1633 
1634 
1635 	}
1636 
1637 	if(strlen(PCLmPageContent->mediaSizeName))
1638 		strncpy(currMediaName,PCLmPageContent->mediaSizeName,256);
1639 
1640 	currStripHeight=PCLmPageContent->stripHeight;
1641 	if(!currStripHeight)
1642 	{
1643 		numImageStrips=1;
1644 		currStripHeight=currSourceHeight;
1645 	}
1646 	else
1647 	{
1648 		float numImageStripsReal=ceil((float)currSourceHeight/(float)currStripHeight); // Need to know how many strips will be inserted into PDF file
1649 		numImageStrips=(int)numImageStripsReal;
1650 		//if(topMarginInPix) // We will inject an extra image for the topMargin offset
1651 		//  numImageStrips++;
1652 	}
1653 
1654 	if(PCLmPageContent->srcColorSpaceSpefication==grayScale)
1655 		srcNumComponents=1;
1656 	else
1657 		srcNumComponents=3;
1658 
1659 	if(PCLmPageContent->dstColorSpaceSpefication==grayScale)
1660 		dstNumComponents=1;
1661 	else
1662 		dstNumComponents=3;
1663 
1664 	currDuplexDisposition=PCLmPageContent->duplexDisposition;
1665 
1666 	destColorSpace=PCLmPageContent->dstColorSpaceSpefication;
1667 
1668 	// Calculate how large the output buffer needs to be based upon the page specifications
1669 	int tmp_outBuffSize=mediaWidthInPixels*currStripHeight*dstNumComponents;
1670 
1671 	if(tmp_outBuffSize>currOutBuffSize)
1672 	{
1673 		*pOutBuffer=realloc(*pOutBuffer,tmp_outBuffSize);  // Realloc the pOutBuffer to the correct size
1674 
1675 		if(*pOutBuffer==NULL)                              //realloc failed and prev buffer not freed
1676 		{
1677 			return errorOutAndCleanUp();
1678 		}
1679 
1680 		outBuffSize=currOutBuffSize=tmp_outBuffSize;
1681 		allocatedOutputBuffer=*pOutBuffer;
1682 		if(NULL == allocatedOutputBuffer)
1683 		{
1684 			return (errorOutAndCleanUp());
1685 		}
1686 		/*if(DebugIt2)
1687 		printf("pOutBuffer: allocated %d bytes at 0x%lx\n",tmp_outBuffSize, (long int)*pOutBuffer);*/
1688 	}
1689 
1690 	initOutBuff((char*)*pOutBuffer,outBuffSize);
1691 
1692 	if(DebugIt2)
1693         dbglog("Allocated %d for myOutBufferSize\n",outBuffSize);
1694 
1695 
1696 
1697 	if(DebugIt)
1698         dbglog("numImageStrips=%d\n",numImageStrips);
1699 	// Keep track of the page count
1700 	pageCount++;
1701 
1702 	// If we are on a backside and doing duplex, prep for reverse strip order
1703 	if(currDuplexDisposition==duplex_longEdge && !(pageCount%2))
1704 	{
1705 		if(DebugIt2)
1706 			dbglog("genPCLm.cpp: setting reverseOrder\n");
1707 		reverseOrder=true;
1708 	}
1709 	else
1710 		reverseOrder=false;
1711 
1712 	// Calculate the number of injected strips, if any
1713 	if(topMarginInPix)
1714 	{
1715 		if(topMarginInPix<=currStripHeight)
1716 		{
1717 			numFullInjectedStrips=1;
1718 			numFullScanlinesToInject=topMarginInPix;
1719 			numPartialScanlinesToInject=0;
1720 		}
1721 		else
1722 		{
1723 			numFullInjectedStrips=topMarginInPix/currStripHeight;
1724 			numFullScanlinesToInject=currStripHeight;
1725 			numPartialScanlinesToInject=topMarginInPix - (numFullInjectedStrips*currStripHeight);
1726 		}
1727 	}
1728 
1729 	writeJobTicket();
1730 	writePDFGrammarPage(mediaWidthInPixels, mediaHeightInPixels, numImageStrips, destColorSpace);
1731 	*iOutBufferSize=totalBytesWrittenToCurrBuff;
1732 
1733 	if(!scratchBuffer)
1734 	{
1735 		// We need to pad the scratchBuffer size to allow for compression expansion (RLE can create
1736 		// compressed segments that are slightly larger than the source.
1737 		scratchBuffer=(ubyte*)malloc(currStripHeight*mediaWidthInPixels*srcNumComponents*2);
1738 		if(!scratchBuffer)
1739 			return(errorOutAndCleanUp());
1740 		/*if(DebugIt2)
1741 		printf("scrachBuffer: Allocated %d bytes at 0x%lx\n",currStripHeight*currSourceWidth*srcNumComponents, (long int) scratchBuffer);*/
1742 	}
1743 
1744 	mirrorBackside=PCLmPageContent->mirrorBackside;
1745 	firstStrip=true;
1746 
1747 	return(success);
1748 }
1749 
1750 /* EndPage
1751 *
1752 * /desc
1753 * /param
1754 * /return
1755 */
EndPage(void ** pOutBuffer,int * iOutBufferSize)1756 int  PCLmGenerator::EndPage(void **pOutBuffer, int *iOutBufferSize)
1757 {
1758 	*pOutBuffer = allocatedOutputBuffer;
1759 	initOutBuff((char*)*pOutBuffer,outBuffSize);
1760 	*iOutBufferSize=totalBytesWrittenToCurrBuff;
1761 
1762 	// Free up the scratchbuffer at endpage, to allow the next page to be declared with a different
1763 	// size.
1764 	if(scratchBuffer)
1765 	{
1766 		free(scratchBuffer);
1767 		scratchBuffer=NULL;
1768 	}
1769 
1770 	return(success);
1771 }
1772 
1773 /* SkipLines
1774 *
1775 * /desc
1776 * /param
1777 * /return
1778 */
SkipLines(int iSkipLines)1779 int  PCLmGenerator::SkipLines(int iSkipLines)
1780 {
1781 	return(success);
1782 }
1783 
1784 /* Encapsulate
1785 *
1786 * /desc
1787 * /param
1788 * /return
1789 */
Encapsulate(void * pInBuffer,int inBufferSize,int thisHeight,void ** pOutBuffer,int * iOutBufferSize)1790 int  PCLmGenerator::Encapsulate(void *pInBuffer, int inBufferSize, int thisHeight, void **pOutBuffer, int *iOutBufferSize)
1791 {
1792 	int result=0, numCompBytes;
1793 	int scanlineWidth=mediaWidthInPixels*srcNumComponents;
1794 	int compSize;
1795 	// int numLinesThisCall=inBufferSize/(currSourceWidth*srcNumComponents);
1796 	int numLinesThisCall=thisHeight;
1797 	//void *savedInBufferPtr=NULL;
1798 	//void *tmpBuffer=NULL;
1799 	void *localInBuffer;
1800 	ubyte *newStripPtr=NULL;
1801 
1802 	/*Coverity CID: 63762: The two blocks in #if 0 here are related to buffering the scan lines if they are more
1803 	than strip height. The memory access is with mediaWidth whereas it should be currSourceWidth(19thApr11 mail)
1804 	plus coverity reported leaks. Since the number of lines passed from PCLmS.cpp will always be <= strip height,
1805 	disabling them and returning fail for that case. */
1806 
1807 	// writeOutputFile(currSourceWidth*3*currStripHeight, (ubyte*)pInBuffer, m_pPCLmSSettings->user_name);
1808 #if 0
1809 	if(leftoverScanlineBuffer)
1810 	{
1811 		ubyte *whereAreWe;
1812 		sint32 scanlinesThisTime;
1813 		// The leftover scanlines have already been processed (color-converted and flipped), so just
1814 		// put them into the output buffer.
1815 		// Allocate a temporary buffer to copy leftover and new data into
1816 		tmpBuffer=malloc(scanlineWidth*currStripHeight);
1817 		if(!tmpBuffer)
1818 			return(errorOutAndCleanUp());
1819 
1820 		// Copy leftover scanlines into tmpBuffer
1821 		memcpy(tmpBuffer,leftoverScanlineBuffer,scanlineWidth*numLeftoverScanlines);
1822 
1823 		whereAreWe=(ubyte*)tmpBuffer+(scanlineWidth*numLeftoverScanlines);
1824 
1825 		scanlinesThisTime=currStripHeight-numLeftoverScanlines;
1826 
1827 		// Copy enough scanlines from the real inBuffer to fill out the tmpBuffer
1828 		memcpy(whereAreWe,pInBuffer,scanlinesThisTime*scanlineWidth);
1829 
1830 		// Now copy the remaining scanlines from pInBuffer to the leftoverBuffer
1831 		if(DebugIt)
1832 			dbglog("Leftover scanlines: numLinesThisCall=%d, currStripHeight=%d\n",numLinesThisCall,currStripHeight);
1833 		numLeftoverScanlines=thisHeight-scanlinesThisTime;
1834 		assert(leftoverScanlineBuffer);
1835 		whereAreWe=(ubyte*)pInBuffer+(scanlineWidth*numLeftoverScanlines);
1836 		memcpy(leftoverScanlineBuffer,whereAreWe,scanlineWidth*numLeftoverScanlines);
1837 		numLinesThisCall=thisHeight=currStripHeight;
1838 
1839 		savedInBufferPtr=pInBuffer;
1840 		localInBuffer=tmpBuffer;
1841 	}
1842 	else
1843 #endif
1844 		localInBuffer=pInBuffer;
1845 
1846 
1847 	//Not handling strip > strip height; see comment above
1848 	if(thisHeight > currStripHeight)
1849 	{
1850 		return ((int)(genericFailure));
1851 #if 0
1852 		// Copy raw raster into leftoverScanlineBuffer
1853 		ubyte *ptr;
1854 		if(DebugIt)
1855 			dbglog("Leftover scanlines: numLinesThisCall=%d, currStripHeight=%d\n",numLinesThisCall,currStripHeight);
1856 		numLeftoverScanlines=thisHeight-currStripHeight;
1857 		leftoverScanlineBuffer=malloc(scanlineWidth*numLeftoverScanlines);
1858 		if(!leftoverScanlineBuffer)
1859 			return(errorOutAndCleanUp());
1860 		ptr=(ubyte *)localInBuffer+scanlineWidth*numLeftoverScanlines;
1861 		memcpy(leftoverScanlineBuffer,ptr,scanlineWidth*numLeftoverScanlines);
1862 		thisHeight=currStripHeight;
1863 #endif
1864 	}
1865 
1866 	if(NULL == allocatedOutputBuffer)
1867 	{
1868 		return (errorOutAndCleanUp());
1869 	}
1870 	*pOutBuffer = allocatedOutputBuffer;
1871 	initOutBuff((char*)*pOutBuffer,outBuffSize);
1872 
1873 	if(currDuplexDisposition==duplex_longEdge && !(pageCount%2))
1874 	{
1875 		if(mirrorBackside)
1876 			prepImageForBacksideDuplex((ubyte*)localInBuffer, numLinesThisCall, currSourceWidth, srcNumComponents);
1877 	}
1878 
1879 	if((destColorSpace==grayScale) && (sourceColorSpace==deviceRGB || sourceColorSpace==adobeRGB))
1880 	{
1881 		colorConvertSource(sourceColorSpace, grayScale, (ubyte*)localInBuffer, currSourceWidth, numLinesThisCall);
1882 		// Adjust the scanline width accordingly
1883 		scanlineWidth = mediaWidthInPixels * dstNumComponents;
1884 	}
1885 
1886 	if(leftMarginInPix)
1887 	{
1888 		newStripPtr=shiftStripByLeftMargin((ubyte*)localInBuffer, currSourceWidth, currStripHeight, numLinesThisCall, mediaWidthInPixels, leftMarginInPix, destColorSpace);
1889 #if 0
1890 		if(sourceColorSpace==grayScale)
1891 			writeOutputFile(currStripHeight*mediaWidthInPixels,(ubyte*)newStripPtr, m_pPCLmSSettings->user_name);
1892 		else
1893 			writeOutputFile(3*currStripHeight*mediaWidthInPixels,(ubyte*)newStripPtr, m_pPCLmSSettings->user_name);
1894 #endif
1895 	}
1896 
1897 #ifdef SUPPORT_WHITE_STRIPS
1898 	bool whiteStrip=isWhiteStrip(pInBuffer, thisHeight*currSourceWidth*srcNumComponents);
1899 	if(DebugIt2)
1900 	{
1901 		if(whiteStrip){
1902 			dbglog("Found white strip\n");
1903 			}
1904 		else{
1905 			dbglog("Found non-white strip\n");
1906 			}
1907 	}
1908 #else
1909 	bool whiteStrip=false;
1910 #endif
1911 
1912 	if(currCompressionDisposition==compressDCT)
1913 	{
1914 		if(firstStrip && topMarginInPix)
1915 		{
1916 			ubyte whitePt=0xff;
1917 
1918 			ubyte *tmpStrip=(ubyte*)malloc(scanlineWidth*topMarginInPix);
1919 			memset(tmpStrip,whitePt,scanlineWidth*topMarginInPix);
1920 
1921 
1922 			for(sint32 stripCntr=0; stripCntr<numFullInjectedStrips;stripCntr++)
1923 			{
1924 				write_JPEG_Buff (scratchBuffer, JPEG_QUALITY, mediaWidthInPixels, (sint32)numFullScanlinesToInject, (JSAMPLE*)tmpStrip, currRenderResolutionInteger, destColorSpace, &numCompBytes);
1925 				injectJPEG((char*)scratchBuffer, mediaWidthInPixels, (sint32)numFullScanlinesToInject, numCompBytes, destColorSpace, true /*white*/ );
1926 			}
1927 
1928 			if(numPartialScanlinesToInject)
1929 			{
1930 				// Handle the leftover strip
1931 				write_JPEG_Buff (scratchBuffer, JPEG_QUALITY, mediaWidthInPixels, numPartialScanlinesToInject, (JSAMPLE*)tmpStrip, currRenderResolutionInteger, destColorSpace, &numCompBytes);
1932 				injectJPEG((char*)scratchBuffer, mediaWidthInPixels, numPartialScanlinesToInject, numCompBytes, destColorSpace, true /*white*/ );
1933 			}
1934 
1935 			free(tmpStrip);
1936 			firstStrip=false;
1937 		}
1938 
1939 		/*The "if 1" block below pads the incoming buffer from numLinesThisCall to strip_height assuming that it has
1940 		that much extra space.
1941 		Also "else" block after this "if 1" block was used before; when for JPEG also, there was no padding to strip_height.
1942 		Retaining it just in case, in future, the padding has to be removed*/
1943 
1944 #if 1
1945 		// We are always going to compress the full strip height, even though the image may be less;
1946 		// this allows the compressed images to be symetric
1947 		if(numLinesThisCall<currStripHeight)
1948 		{
1949 			sint32 numLeftoverBytes=(currStripHeight-numLinesThisCall)*currSourceWidth*3;
1950 			sint32 numImagedBytes  =numLinesThisCall*currSourceWidth*3;
1951 			// End-of-page: we have to white-out the unused section of the source image
1952 			memset((ubyte*)localInBuffer+numImagedBytes, 0xff, numLeftoverBytes);
1953 		}
1954 
1955 		if(newStripPtr)
1956 		{
1957 			write_JPEG_Buff (scratchBuffer, JPEG_QUALITY, mediaWidthInPixels, currStripHeight, (JSAMPLE*)newStripPtr, currRenderResolutionInteger, destColorSpace, &numCompBytes);
1958 			free(newStripPtr);
1959 			newStripPtr = NULL;
1960 		}
1961 		else
1962 			write_JPEG_Buff (scratchBuffer, JPEG_QUALITY, mediaWidthInPixels, currStripHeight, (JSAMPLE*)localInBuffer, currRenderResolutionInteger, destColorSpace, &numCompBytes);
1963 
1964 		if(DebugIt2)
1965 			writeOutputFile(numCompBytes, scratchBuffer, m_pPCLmSSettings->user_name);
1966 		injectJPEG((char*)scratchBuffer, mediaWidthInPixels, currStripHeight, numCompBytes, destColorSpace, whiteStrip );
1967 
1968 #else
1969 		if(newStripPtr)
1970 		{
1971 			write_JPEG_Buff (scratchBuffer, JPEG_QUALITY, mediaWidthInPixels, numLinesThisCall, (JSAMPLE*)newStripPtr, currRenderResolutionInteger, destColorSpace, &numCompBytes);
1972 			free(newStripPtr);
1973 			newStripPtr = NULL;
1974 		}
1975 		else
1976 			write_JPEG_Buff (scratchBuffer, JPEG_QUALITY, mediaWidthInPixels, numLinesThisCall, (JSAMPLE*)localInBuffer, currRenderResolutionInteger, destColorSpace, &numCompBytes);
1977 		if(DebugIt2)
1978 			writeOutputFile(numCompBytes, scratchBuffer, m_pPCLmSSettings->user_name);
1979 		injectJPEG((char*)scratchBuffer, mediaWidthInPixels, numLinesThisCall, numCompBytes, destColorSpace, whiteStrip );
1980 #endif
1981 	}
1982 	else if(currCompressionDisposition==compressFlate)
1983 	{
1984 		uint32 len=numLinesThisCall*scanlineWidth;
1985 		uLongf destSize=len;
1986 
1987 		if(firstStrip && topMarginInPix)
1988 		{
1989 			ubyte whitePt=0xff;
1990 
1991 			// We need to inject a blank image-strip with a height==topMarginInPix
1992 			ubyte *tmpStrip=(ubyte*)malloc(scanlineWidth*topMarginInPix);
1993 			uLongf tmpDestSize=destSize;
1994 			memset(tmpStrip,whitePt,scanlineWidth*topMarginInPix);
1995 
1996 			for(sint32 stripCntr=0; stripCntr<numFullInjectedStrips;stripCntr++)
1997 			{
1998 				result=compress((Bytef*)scratchBuffer,&tmpDestSize, (const Bytef*)tmpStrip, scanlineWidth*numFullScanlinesToInject);
1999 				injectLZStrip((ubyte*)scratchBuffer, tmpDestSize, mediaWidthInPixels, numFullScanlinesToInject, destColorSpace, true /*white*/ );
2000 			}
2001 			if(numPartialScanlinesToInject)
2002 			{
2003 				result=compress((Bytef*)scratchBuffer,&tmpDestSize, (const Bytef*)tmpStrip, scanlineWidth*numPartialScanlinesToInject);
2004 				injectLZStrip((ubyte*)scratchBuffer, tmpDestSize, mediaWidthInPixels, numPartialScanlinesToInject, destColorSpace, true /*white*/ );
2005 			}
2006 			free(tmpStrip);
2007 			firstStrip=false;
2008 		}
2009 
2010 		if(newStripPtr)
2011 		{
2012         result=compress((Bytef*)scratchBuffer,&destSize,(const Bytef*)newStripPtr,scanlineWidth*numLinesThisCall);
2013         if(DebugIt2)
2014           writeOutputFile(destSize, scratchBuffer, m_pPCLmSSettings->user_name);
2015         if(DebugIt2)
2016         {
2017           dbglog("Allocated zlib dest buffer of size %d\n",numLinesThisCall*scanlineWidth);
2018           dbglog("zlib compression return result=%d, compSize=%d\n",result,(int)destSize);
2019         }
2020 			free(newStripPtr);
2021 			newStripPtr = NULL;
2022 		}
2023 		else
2024       {
2025         result=compress((Bytef*)scratchBuffer, &destSize, (const Bytef*)localInBuffer, scanlineWidth*numLinesThisCall);
2026         if(DebugIt2)
2027           writeOutputFile(destSize, scratchBuffer, m_pPCLmSSettings->user_name);
2028         if(DebugIt2)
2029         {
2030           dbglog("Allocated zlib dest buffer of size %d\n",numLinesThisCall*scanlineWidth);
2031           dbglog("zlib compression return result=%d, compSize=%d\n",result,(int)destSize);
2032         }
2033 		}
2034 		injectLZStrip(scratchBuffer,destSize, mediaWidthInPixels, numLinesThisCall, destColorSpace, whiteStrip);
2035 	}
2036 
2037 	else if(currCompressionDisposition==compressRLE)
2038 	{
2039 		if(firstStrip && topMarginInPix)
2040 		{
2041 			ubyte whitePt=0xff;
2042 
2043 			// We need to inject a blank image-strip with a height==topMarginInPix
2044 
2045 			ubyte *tmpStrip=(ubyte*)malloc(scanlineWidth*topMarginInPix);
2046 			memset(tmpStrip,whitePt,scanlineWidth*topMarginInPix);
2047 
2048 			for(sint32 stripCntr=0; stripCntr<numFullInjectedStrips;stripCntr++)
2049 			{
2050 				compSize=HPRunLen_Encode((ubyte*)tmpStrip, scratchBuffer, scanlineWidth*numFullScanlinesToInject);
2051 				injectRLEStrip((ubyte*)scratchBuffer, compSize, mediaWidthInPixels, numFullScanlinesToInject, destColorSpace, true /*white*/);
2052 			}
2053 
2054 			if(numPartialScanlinesToInject)
2055 			{
2056 				compSize=HPRunLen_Encode((ubyte*)tmpStrip, scratchBuffer, scanlineWidth*numPartialScanlinesToInject);
2057 				injectRLEStrip((ubyte*)scratchBuffer, compSize, mediaWidthInPixels, numPartialScanlinesToInject, destColorSpace, true /*white*/);
2058 			}
2059 
2060 			free(tmpStrip);
2061 			firstStrip=false;
2062 		}
2063 
2064 		if(newStripPtr)
2065 		{
2066 			compSize=HPRunLen_Encode((ubyte*)newStripPtr, scratchBuffer, scanlineWidth*numLinesThisCall);
2067 			free(newStripPtr);
2068 			newStripPtr = NULL;
2069 		}
2070 		else
2071 			compSize=HPRunLen_Encode((ubyte*)localInBuffer, scratchBuffer, scanlineWidth*numLinesThisCall);
2072 
2073 		if(DebugIt2)
2074 		{
2075 			dbglog("Allocated rle dest buffer of size %d\n",numLinesThisCall*scanlineWidth);
2076 			dbglog("rle compression return size=%d=%d\n",result,(int)compSize);
2077 		}
2078 		injectRLEStrip(scratchBuffer, compSize, mediaWidthInPixels, numLinesThisCall, destColorSpace, whiteStrip);
2079 	}
2080 	else
2081 		assert(0);
2082 
2083 	*iOutBufferSize=totalBytesWrittenToCurrBuff;
2084 
2085 	/*if(savedInBufferPtr)
2086 		pInBuffer=savedInBufferPtr;
2087 
2088 	if(tmpBuffer)
2089 		free(tmpBuffer);*/
2090 
2091 	if(newStripPtr)
2092 	{
2093 		free(newStripPtr);
2094 		newStripPtr = NULL;
2095 	}
2096 	return(success);
2097 }
2098 
2099 /* FreeBuffer
2100 *
2101 * /desc
2102 * /param
2103 * /return
2104 */
FreeBuffer(void * pBuffer)2105 void PCLmGenerator::FreeBuffer(void *pBuffer)
2106 {
2107 	if(jobOpen==job_closed && pBuffer)
2108 	{
2109 
2110 		if(pBuffer == allocatedOutputBuffer)
2111 		{
2112 			allocatedOutputBuffer = NULL;
2113 		}
2114 		free(pBuffer);
2115 	}
2116 	pBuffer=NULL;
2117 }
2118 
2119 
2120