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