Tizen 2.1 base
[platform/upstream/hplip.git] / ip / xfakemono.c
1 /* libhpojip -- HP OfficeJet image-processing library. */
2
3 /* Copyright (C) 1995-2002 Hewlett-Packard Company
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
12  * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
13  * NON-INFRINGEMENT.  See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18  * MA 02111-1307, USA.
19  *
20  * In addition, as a special exception, Hewlett-Packard Company
21  * gives permission to link the code of this program with any
22  * version of the OpenSSL library which is distributed under a
23  * license identical to that listed in the included LICENSE.OpenSSL
24  * file, and distribute linked combinations including the two.
25  * You must obey the GNU General Public License in all respects
26  * for all of the code used other than OpenSSL.  If you modify
27  * this file, you may extend this exception to your version of the
28  * file, but you are not obligated to do so.  If you do not wish to
29  * do so, delete this exception statement from your version.
30  */
31
32 /* Original author: Mark Overton and others.
33  *
34  * Ported to Linux by David Paschal.
35  */
36
37 /******************************************************************************\
38  *
39  * xfakemono.c - Simulates grayscale or bilevel in 24-bit data.
40  *
41  ******************************************************************************
42  *
43  * Name of Global Jump-Table:
44  *
45  *    fakeMonoTbl
46  *
47  * Items in aXformInfo array passed into setXformSpec:
48  *
49  *    aXformInfo[IP_FAKE_MONO_BPP] = 8 or 1, to simulate grayscale or mono
50  *
51  * Capabilities and Limitations:
52  *
53  *    The input and output image are 24-bits per pixel.  But the output image
54  *    will *appear* to be grayscale if aXformInfo[0] == 8, or bilevel if it == 1.
55  *
56  * Default Input Traits, and Output Traits:
57  *
58  *          trait             default input             output
59  *    -------------------  ---------------------  ------------------------
60  *    iPixelsPerRow         * passed into output   same as default input
61  *    iBitsPerPixel         * must be 24           24
62  *    iComponentsPerPixel   * must be 3            3
63  *    lHorizDPI               passed into output   same as default input
64  *    lVertDPI                passed into output   same as default input
65  *    lNumRows                passed into output   same as default input
66  *    iNumPages               passed into output   same as default input
67  *    iPageNum                passed into output   same as default input
68  *
69  *    Above, a "*" by an item indicates it must be valid (not negative).
70  *
71 \******************************************************************************/
72
73 // Use the #define below if this transform will exist in a dll outside of the
74 // image pipeline.  This will allow the functions to be exported.
75 // #define EXPORT_TRANFORM 1
76
77 #include "hpip.h"
78 #include "ipdefs.h"
79 #include "string.h"    /* for memset and memcpy */
80
81
82 #if 0
83     #include "stdio.h"
84     #include <tchar.h>
85     #define PRINT(msg,arg1,arg2) \
86         _ftprintf(stderr, msg, (int)arg1, (int)arg2)
87 #else
88     #define PRINT(msg,arg1,arg2)
89 #endif
90
91 #define CHECK_VALUE 0x4ba1dace
92
93 #ifdef EXPORT_TRANSFORM
94 #define FUNC_STATUS __declspec (dllexport)
95 #else
96 #define FUNC_STATUS static
97 #endif
98
99 typedef struct {
100     IP_IMAGE_TRAITS traits;   /* traits of the input and output image */
101     int      iFakeDPI;        /* dpi to fake (8 or 1) */
102     DWORD    dwBytesPerRow;   /* # of bytes in each row */
103     DWORD    dwRowsDone;      /* number of rows converted so far */
104     DWORD    dwInNextPos;     /* file pos for subsequent input */
105     DWORD    dwOutNextPos;    /* file pos for subsequent output */
106     DWORD    dwValidChk;      /* struct validity check value */
107 } FMON_INST, *PFMON_INST;
108
109
110
111 /*****************************************************************************\
112  *
113  * fakeMono_openXform - Creates a new instance of the transformer
114  *
115  *****************************************************************************
116  *
117  * This returns a handle for the new instance to be passed into
118  * all subsequent calls.
119  *
120  * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
121  *
122 \*****************************************************************************/
123
124 FUNC_STATUS WORD fakeMono_openXform (
125     IP_XFORM_HANDLE *pXform)   /* out: returned handle */
126 {
127     PFMON_INST g;
128
129     INSURE (pXform != NULL);
130     IP_MEM_ALLOC (sizeof(FMON_INST), g);
131     *pXform = g;
132     memset (g, 0, sizeof(FMON_INST));
133     g->dwValidChk = CHECK_VALUE;
134     g->iFakeDPI = 8;
135     return IP_DONE;
136
137     fatal_error:
138     return IP_FATAL_ERROR;
139 }
140
141
142
143 /*****************************************************************************\
144  *
145  * fakeMono_setDefaultInputTraits - Specifies default input image traits
146  *
147  *****************************************************************************
148  *
149  * The header of the file-type handled by the transform probably does
150  * not include *all* the image traits we'd like to know.  Those not
151  * specified in the file-header are filled in from info provided by
152  * this routine.
153  *
154  * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
155  *
156 \*****************************************************************************/
157
158 FUNC_STATUS WORD fakeMono_setDefaultInputTraits (
159     IP_XFORM_HANDLE  hXform,     /* in: handle for xform */
160     PIP_IMAGE_TRAITS pTraits)    /* in: default image traits */
161 {
162     PFMON_INST g;
163
164     HANDLE_TO_PTR (hXform, g);
165
166     /* insure that traits we care about are known */
167     INSURE (pTraits->iPixelsPerRow > 0 &&
168             pTraits->iBitsPerPixel == 24 &&
169             pTraits->iComponentsPerPixel == 3);
170
171     g->traits = *pTraits;   /* a structure copy */
172     g->dwBytesPerRow = (g->traits.iPixelsPerRow*g->traits.iBitsPerPixel + 7) / 8;
173     return IP_DONE;
174
175     fatal_error:
176     return IP_FATAL_ERROR;
177 }
178
179
180
181 /*****************************************************************************\
182  *
183  * fakeMono_setXformSpec - Provides xform-specific information
184  *
185 \*****************************************************************************/
186
187 FUNC_STATUS WORD fakeMono_setXformSpec (
188     IP_XFORM_HANDLE hXform,         /* in: handle for xform */
189     DWORD_OR_PVOID  aXformInfo[])   /* in: xform information */
190 {
191     PFMON_INST g;
192     HANDLE_TO_PTR (hXform, g);
193     g->iFakeDPI = aXformInfo[IP_FAKE_MONO_BPP].dword;
194     INSURE (g->iFakeDPI==1 || g->iFakeDPI==8);
195     return IP_DONE;
196
197     fatal_error:
198     return IP_FATAL_ERROR;
199 }
200
201
202
203 /*****************************************************************************\
204  *
205  * fakeMono_getHeaderBufSize- Returns size of input buf needed to hold header
206  *
207 \*****************************************************************************/
208
209 FUNC_STATUS WORD fakeMono_getHeaderBufSize (
210     IP_XFORM_HANDLE  hXform,         /* in:  handle for xform */
211     DWORD           *pdwInBufLen)    /* out: buf size for parsing header */
212 {
213     /* since input is raw pixels, there is no header, so set it to zero */
214     *pdwInBufLen = 0;
215     return IP_DONE;
216 }
217
218
219
220 /*****************************************************************************\
221  *
222  * fakeMono_getActualTraits - Parses header, and returns input & output traits
223  *
224 \*****************************************************************************/
225
226 FUNC_STATUS WORD fakeMono_getActualTraits (
227     IP_XFORM_HANDLE  hXform,         /* in:  handle for xform */
228     DWORD            dwInputAvail,   /* in:  # avail bytes in input buf */
229     PBYTE            pbInputBuf,     /* in:  ptr to input buffer */
230     PDWORD           pdwInputUsed,   /* out: # bytes used from input buf */
231     PDWORD           pdwInputNextPos,/* out: file-pos to read from next */
232     PIP_IMAGE_TRAITS pIntraits,      /* out: input image traits */
233     PIP_IMAGE_TRAITS pOutTraits)     /* out: output image traits */
234 {
235     PFMON_INST g;
236
237     HANDLE_TO_PTR (hXform, g);
238
239     /* Since there is no header, we'll report no usage of input */
240     *pdwInputUsed    = 0;
241     *pdwInputNextPos = 0;
242
243     *pIntraits  = g->traits;   /* structure copies */
244     *pOutTraits = g->traits;
245
246     return IP_DONE | IP_READY_FOR_DATA;
247
248     fatal_error:
249     return IP_FATAL_ERROR;
250 }
251
252
253
254 /****************************************************************************\
255  *
256  * fakeMono_getActualBufSizes - Returns buf sizes needed for remainder of job
257  *
258 \****************************************************************************/
259
260 FUNC_STATUS WORD fakeMono_getActualBufSizes (
261     IP_XFORM_HANDLE hXform,          /* in:  handle for xform */
262     PDWORD          pdwMinInBufLen,  /* out: min input buf size */
263     PDWORD          pdwMinOutBufLen) /* out: min output buf size */
264 {
265     PFMON_INST g;
266     HANDLE_TO_PTR (hXform, g);
267     *pdwMinInBufLen = *pdwMinOutBufLen = g->dwBytesPerRow;
268     return IP_DONE;
269
270     fatal_error:
271     return IP_FATAL_ERROR;
272 }
273
274
275
276 /*****************************************************************************\
277  *
278  * fakeMono_convert - Converts one row
279  *
280 \*****************************************************************************/
281
282 FUNC_STATUS WORD fakeMono_convert (
283     IP_XFORM_HANDLE hXform,
284     DWORD           dwInputAvail,     /* in:  # avail bytes in in-buf */
285     PBYTE           pbInputBuf,       /* in:  ptr to in-buffer */
286     PDWORD          pdwInputUsed,     /* out: # bytes used from in-buf */
287     PDWORD          pdwInputNextPos,  /* out: file-pos to read from next */
288     DWORD           dwOutputAvail,    /* in:  # avail bytes in out-buf */
289     PBYTE           pbOutputBuf,      /* in:  ptr to out-buffer */
290     PDWORD          pdwOutputUsed,    /* out: # bytes written in out-buf */
291     PDWORD          pdwOutputThisPos) /* out: file-pos to write the data */
292 {
293     PFMON_INST g;
294     int       nBytes;
295     PBYTE     pIn, pInAfter, pOut;
296     unsigned  rv, gv, bv;
297     int       gray;
298
299     HANDLE_TO_PTR (hXform, g);
300
301     /**** Check if we were told to flush ****/
302
303     if (pbInputBuf == NULL) {
304         PRINT (_T("fakeMono_convert: Told to flush.\n"), 0, 0);
305         *pdwInputUsed = *pdwOutputUsed = 0;
306         *pdwInputNextPos  = g->dwInNextPos;
307         *pdwOutputThisPos = g->dwOutNextPos;
308         return IP_DONE;
309     }
310
311     /**** Output a Row ****/
312
313     nBytes = g->dwBytesPerRow;
314     INSURE (dwInputAvail  >= (DWORD)nBytes );
315     INSURE (dwOutputAvail >= (DWORD)nBytes);
316
317     pIn  = pbInputBuf;
318     pOut = pbOutputBuf;
319     pInAfter = pIn + nBytes;
320
321     if (g->iFakeDPI == 1) {   // faking bi-level
322         while (pIn < pInAfter) {
323             rv = *pIn++;
324             gv = *pIn++;
325             bv = *pIn++;
326             gray = NTSC_LUMINANCE (rv, gv, bv);
327             gray = (gray >= 128) ? 255 : 0;
328             *pOut++ = (BYTE)gray;
329             *pOut++ = (BYTE)gray;
330             *pOut++ = (BYTE)gray;
331         }
332     } else {   // faking grayscale
333         while (pIn < pInAfter) {
334             rv = *pIn++;
335             gv = *pIn++;
336             bv = *pIn++;
337             gray = NTSC_LUMINANCE (rv, gv, bv);
338             *pOut++ = (BYTE)gray;
339             *pOut++ = (BYTE)gray;
340             *pOut++ = (BYTE)gray;
341         }
342     }
343
344     *pdwInputUsed     = nBytes;
345     g->dwInNextPos   += nBytes;
346     *pdwInputNextPos  = g->dwInNextPos;
347
348     *pdwOutputUsed    = nBytes;
349     *pdwOutputThisPos = g->dwOutNextPos;
350     g->dwOutNextPos  += nBytes;
351
352     g->dwRowsDone += 1;
353
354     return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
355
356     fatal_error:
357     return IP_FATAL_ERROR;
358 }
359
360
361
362 /*****************************************************************************\
363  *
364  * fakeMono_insertedData - client inserted into our output stream
365  *
366 \*****************************************************************************/
367
368 FUNC_STATUS WORD fakeMono_insertedData (
369     IP_XFORM_HANDLE hXform,
370     DWORD           dwNumBytes)
371 {
372     fatalBreakPoint ();
373     return IP_FATAL_ERROR;   /* must never be called (can't insert data) */
374 }
375
376
377
378 /*****************************************************************************\
379  *
380  * fakeMono_newPage - Tells us to flush this page, and start a new page
381  *
382 \*****************************************************************************/
383
384 FUNC_STATUS WORD fakeMono_newPage (
385     IP_XFORM_HANDLE hXform)
386 {
387     PFMON_INST g;
388
389     HANDLE_TO_PTR (hXform, g);
390     /* todo: return fatal error if convert is called again? */
391     return IP_DONE;   /* can't insert page-breaks, so ignore this call */
392
393     fatal_error:
394     return IP_FATAL_ERROR;
395
396 }
397
398
399
400 /*****************************************************************************\
401  *
402  * fakeMono_closeXform - Destroys this instance
403  *
404 \*****************************************************************************/
405
406 FUNC_STATUS WORD fakeMono_closeXform (IP_XFORM_HANDLE hXform)
407 {
408     PFMON_INST g;
409
410     HANDLE_TO_PTR (hXform, g);
411
412     g->dwValidChk = 0;
413     IP_MEM_FREE (g);       /* free memory for the instance */
414
415     return IP_DONE;
416
417     fatal_error:
418     return IP_FATAL_ERROR;
419 }
420
421
422
423 /*****************************************************************************\
424  *
425  * fakeMonoTbl - Jump-table for transform driver
426  *
427 \*****************************************************************************/
428 #ifdef EXPORT_TRANSFORM
429 __declspec (dllexport)
430 #endif
431 IP_XFORM_TBL fakeMonoTbl = {
432     fakeMono_openXform,
433     fakeMono_setDefaultInputTraits,
434     fakeMono_setXformSpec,
435     fakeMono_getHeaderBufSize,
436     fakeMono_getActualTraits,
437     fakeMono_getActualBufSizes,
438     fakeMono_convert,
439     fakeMono_newPage,
440     fakeMono_insertedData,
441     fakeMono_closeXform
442 };
443
444 /* End of File */
445
446
447 /*****************************************************************************\
448  *
449  * ipGetXformTable - Returns pointer to the jump table
450  *
451 \*****************************************************************************/
452
453 #ifdef EXPORT_TRANSFORM
454 EXPORT(WORD) ipGetXformTable (LPIP_XFORM_TBL pXform)
455 {
456     WORD wRet = IP_DONE;
457
458     if (pXform)
459         *pXform = clrmapTbl;
460     else
461         wRet = IP_FATAL_ERROR;
462
463     return wRet;
464 }
465 #endif