1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 * Copyright (C) 2016 Mopria Alliance, Inc.
4 * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#ifndef _PCLM_GENERATOR
20#define _PCLM_GENERATOR
21#define SUPPORT_WHITE_STRIPS
22
23#include "common_defines.h"
24
25/*
26 * Generates a stream of PCLm output.
27 *
28 * Public APIs supply data output data into pOutBuffer with length in iOutBufferSize, to be
29 * delivered to the printer.
30 */
31class PCLmGenerator {
32public:
33
34    PCLmGenerator();
35
36    ~PCLmGenerator();
37
38    /*
39     * Started a PCLm job. Initializes buffers.
40     */
41    int StartJob(void **pOutBuffer, int *iOutBufferSize);
42
43    /*
44     * Ends the PCLm job. Writes trailer, frees buffers and arrays
45     */
46    int EndJob(void **pOutBuffer, int *iOutBufferSize);
47
48    /*
49     * Starts rendering a page of a PCLm job.
50     */
51    int StartPage(PCLmPageSetup *PCLmPageContent, void **pOutBuffer, int *iOutBufferSize);
52
53    /*
54     * Ends rendering a page. Frees scratch buffer.
55     */
56    int EndPage(void **pOutBuffer, int *iOutBufferSize);
57
58    /*
59     * Compresses output buffer in Flate, RLE, or JPEG compression
60     */
61    int Encapsulate(void *pInBuffer, int inBufferSize, int numLines, void **pOutBuffer,
62            int *iOutBufferSize);
63
64    /*
65     * Returns index of matched media size, else returns index for letter
66     */
67    int GetPclmMediaDimensions(const char *mediaRequested, PCLmPageSetup *myPageInfo);
68
69    /*
70     * Free the supplied output buffer (after EndJob)
71     */
72    void FreeBuffer(void *pBuffer);
73
74private:
75    /*
76     * Convert an image from one color space to another.
77     * Currently, only supports RGB->GRAY
78     */
79    bool colorConvertSource(colorSpaceDisposition srcCS, colorSpaceDisposition dstCS, ubyte *strip,
80            sint32 stripWidth, sint32 stripHeight);
81
82    /*
83     * Generates the PDF page construct(s), which includes the image information. The /Length
84     * definition is required for PDF, so we write the stream to a RAM buffer first, then calculate
85     * the Buffer size, insert the PDF /Length construct, then write the buffer to the PDF file.
86     */
87    void writePDFGrammarPage
88            (int imageWidth, int imageHeight, int numStrips, colorSpaceDisposition destColorSpace);
89
90    /*
91     * Writes the PDF and PCLm versions to the output buffer as the header
92     */
93    void writePDFGrammarHeader();
94
95    /*
96     * Injects RLE compression strip into the output buffer
97     */
98    int injectRLEStrip(ubyte *RLEBuffer, int numBytes, int imageWidth, int imageHeight,
99            colorSpaceDisposition destColorSpace, bool);
100
101    /*
102     * Injects zlib compressed strip to the output buffer
103     */
104    int injectLZStrip(ubyte *LZBuffer, int numBytes, int imageWidth, int imageHeight,
105            colorSpaceDisposition destColorSpace, bool);
106
107    /*
108     * Injects jpeg compressed image to the output buffer
109     */
110    int injectJPEG(char *jpeg_Buff, int imageWidth, int imageHeight, int numCompBytes,
111            colorSpaceDisposition destColorSpace, bool);
112
113    /*
114     * Initializes the output buffer with buff and size
115     */
116    void initOutBuff(char *buff, sint32 size);
117
118    /*
119     * Writes str to the outputBuffer
120     */
121    void writeStr2OutBuff(char *str);
122
123    /*
124     * Writes buff to the outputBuffer
125     */
126    void write2Buff(ubyte *buff, int buffSize);
127
128    /*
129     * Adds totalBytesWrittenToPCLmFile to the xRefTable for output
130     */
131    int statOutputFileSize();
132
133    /*
134     * Writes file information to the outputbuffer as the trailer.
135     */
136    void writePDFGrammarTrailer(int imageWidth, int imageHeight);
137
138    /*
139     * Injects Adobe RGBCS into the output buffer
140     */
141    bool injectAdobeRGBCS();
142
143    /*
144     * Adds kidObj to KidsArray
145     */
146    bool addKids(sint32 kidObj);
147
148    /*
149     * Adds xRefObj to the xRefTable
150     */
151    bool addXRef(sint32 xRefObj);
152
153    /*
154     * Warning: take extreme care in modifying this unless you understand what is going on. This
155     * function attempts to fix the xref table, based upon the strips getting inserted in reverse
156     * order (on the backside page). It does the following:
157     *   1) Calculates the new object reference size (using tmpArray)
158     *   2) Adds 2 to the object size to compensate for the offset
159     *   3) Reorders the Image FileBody and the ImageTransformation, as these are 1 PDF object
160     *   4) Frees the tmp array
161     */
162    void fixXRef();
163
164    /*
165     * Calls cleanup and returns an error
166     */
167    int errorOutAndCleanUp();
168
169    /*
170     * Cleans up allocatedOutputBuffer, leftoverScanlineBuffer, scratchBuffer, xRefTable, and
171     * KidsArray
172     */
173    void Cleanup(void);
174
175    /*
176     * Writes job information to the output buffer
177     */
178    void writeJobTicket(void);
179
180    /*
181     * Transforms image for duplexing, writes to output buffer
182     */
183    void injectImageTransform();
184
185#ifdef SUPPORT_WHITE_STRIPS
186
187    /*
188     * Checks if the given buffer is a white strip
189     */
190    bool isWhiteStrip(void *, int);
191
192#endif
193
194    /*
195     * Outputs the string associated with the given bin into returnStr
196     */
197    bool getInputBinString(jobInputBin bin, char *);
198
199    /*
200     * Outputs the string associated with the given bin into returnStr
201     */
202    bool getOutputBin(jobOutputBin bin, char *);
203
204    /*
205     * compress input by identifying repeating bytes (not sequences)
206     * Compression ratio good for grayscale images, not great on RGB
207     * Output:
208     *     1-127:   literal run
209     *     128:     end of compression block
210     *     129-256: repeating byte sequence
211     */
212    int RLEEncodeImage(ubyte *in, ubyte *out, int inLength);
213
214    sint32 currStripHeight;
215    char currMediaName[256];
216    duplexDispositionEnum currDuplexDisposition;
217    compressionDisposition currCompressionDisposition;
218    mediaOrientationDisposition currMediaOrientationDisposition;
219    renderResolution currRenderResolution;
220    int currRenderResolutionInteger;
221    void *allocatedOutputBuffer;
222    void *leftoverScanlineBuffer;
223
224    int mediaWidth;
225    int mediaHeight;
226    int mediaWidthInPixels;
227    int mediaHeightInPixels;
228    colorSpaceDisposition destColorSpace;
229    colorSpaceDisposition sourceColorSpace;
230    int scaleFactor;
231    jobStateEnum jobOpen;
232    int currSourceWidth;
233    int currSourceHeight;
234    int srcNumComponents;
235    int dstNumComponents;
236    int numLeftoverScanlines;
237    ubyte *scratchBuffer;
238    int pageCount;
239    bool reverseOrder;
240    int outBuffSize;
241    int currOutBuffSize;
242    int totalBytesWrittenToPCLmFile;
243    int totalBytesWrittenToCurrBuff;
244    char *outBuffPtr;
245    char *currBuffPtr;
246    float STANDARD_SCALE;
247    sint32 objCounter;
248
249    sint32 yPosition;
250    sint32 pageOrigin;
251    sint32 *KidsArray;
252    sint32 numKids;
253
254    // XRefTable storage
255    sint32 *xRefTable;
256    sint32 xRefIndex;
257    sint32 xRefStart;
258    char pOutStr[256];
259    bool adobeRGBCS_firstTime;
260    bool mirrorBackside;
261    sint32 topMarginInPix;
262    sint32 leftMarginInPix;
263    bool firstStrip;
264    sint32 numFullInjectedStrips;
265    sint32 numFullScanlinesToInject;
266    sint32 numPartialScanlinesToInject;
267
268    PCLmSUserSettingsType *m_pPCLmSSettings;
269};
270
271#endif // _PCLM_PARSER_