1 /* libhpojip -- HP OfficeJet image-processing library. */
3 /* Copyright (C) 1995-2002 Hewlett-Packard Company
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.
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.
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,
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.
32 /* Original author: Mark Overton and others.
34 * Ported to Linux by David Paschal.
37 /******************************************************************************\
39 * xfakemono.c - Simulates grayscale or bilevel in 24-bit data.
41 ******************************************************************************
43 * Name of Global Jump-Table:
47 * Items in aXformInfo array passed into setXformSpec:
49 * aXformInfo[IP_FAKE_MONO_BPP] = 8 or 1, to simulate grayscale or mono
51 * Capabilities and Limitations:
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.
56 * Default Input Traits, and Output Traits:
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
69 * Above, a "*" by an item indicates it must be valid (not negative).
71 \******************************************************************************/
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
79 #include "string.h" /* for memset and memcpy */
85 #define PRINT(msg,arg1,arg2) \
86 _ftprintf(stderr, msg, (int)arg1, (int)arg2)
88 #define PRINT(msg,arg1,arg2)
91 #define CHECK_VALUE 0x4ba1dace
93 #ifdef EXPORT_TRANSFORM
94 #define FUNC_STATUS __declspec (dllexport)
96 #define FUNC_STATUS static
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;
111 /*****************************************************************************\
113 * fakeMono_openXform - Creates a new instance of the transformer
115 *****************************************************************************
117 * This returns a handle for the new instance to be passed into
118 * all subsequent calls.
120 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
122 \*****************************************************************************/
124 FUNC_STATUS WORD fakeMono_openXform (
125 IP_XFORM_HANDLE *pXform) /* out: returned handle */
129 INSURE (pXform != NULL);
130 IP_MEM_ALLOC (sizeof(FMON_INST), g);
132 memset (g, 0, sizeof(FMON_INST));
133 g->dwValidChk = CHECK_VALUE;
138 return IP_FATAL_ERROR;
143 /*****************************************************************************\
145 * fakeMono_setDefaultInputTraits - Specifies default input image traits
147 *****************************************************************************
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
154 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
156 \*****************************************************************************/
158 FUNC_STATUS WORD fakeMono_setDefaultInputTraits (
159 IP_XFORM_HANDLE hXform, /* in: handle for xform */
160 PIP_IMAGE_TRAITS pTraits) /* in: default image traits */
164 HANDLE_TO_PTR (hXform, g);
166 /* insure that traits we care about are known */
167 INSURE (pTraits->iPixelsPerRow > 0 &&
168 pTraits->iBitsPerPixel == 24 &&
169 pTraits->iComponentsPerPixel == 3);
171 g->traits = *pTraits; /* a structure copy */
172 g->dwBytesPerRow = (g->traits.iPixelsPerRow*g->traits.iBitsPerPixel + 7) / 8;
176 return IP_FATAL_ERROR;
181 /*****************************************************************************\
183 * fakeMono_setXformSpec - Provides xform-specific information
185 \*****************************************************************************/
187 FUNC_STATUS WORD fakeMono_setXformSpec (
188 IP_XFORM_HANDLE hXform, /* in: handle for xform */
189 DWORD_OR_PVOID aXformInfo[]) /* in: xform information */
192 HANDLE_TO_PTR (hXform, g);
193 g->iFakeDPI = aXformInfo[IP_FAKE_MONO_BPP].dword;
194 INSURE (g->iFakeDPI==1 || g->iFakeDPI==8);
198 return IP_FATAL_ERROR;
203 /*****************************************************************************\
205 * fakeMono_getHeaderBufSize- Returns size of input buf needed to hold header
207 \*****************************************************************************/
209 FUNC_STATUS WORD fakeMono_getHeaderBufSize (
210 IP_XFORM_HANDLE hXform, /* in: handle for xform */
211 DWORD *pdwInBufLen) /* out: buf size for parsing header */
213 /* since input is raw pixels, there is no header, so set it to zero */
220 /*****************************************************************************\
222 * fakeMono_getActualTraits - Parses header, and returns input & output traits
224 \*****************************************************************************/
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 */
237 HANDLE_TO_PTR (hXform, g);
239 /* Since there is no header, we'll report no usage of input */
241 *pdwInputNextPos = 0;
243 *pIntraits = g->traits; /* structure copies */
244 *pOutTraits = g->traits;
246 return IP_DONE | IP_READY_FOR_DATA;
249 return IP_FATAL_ERROR;
254 /****************************************************************************\
256 * fakeMono_getActualBufSizes - Returns buf sizes needed for remainder of job
258 \****************************************************************************/
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 */
266 HANDLE_TO_PTR (hXform, g);
267 *pdwMinInBufLen = *pdwMinOutBufLen = g->dwBytesPerRow;
271 return IP_FATAL_ERROR;
276 /*****************************************************************************\
278 * fakeMono_convert - Converts one row
280 \*****************************************************************************/
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 */
295 PBYTE pIn, pInAfter, pOut;
299 HANDLE_TO_PTR (hXform, g);
301 /**** Check if we were told to flush ****/
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;
311 /**** Output a Row ****/
313 nBytes = g->dwBytesPerRow;
314 INSURE (dwInputAvail >= (DWORD)nBytes );
315 INSURE (dwOutputAvail >= (DWORD)nBytes);
319 pInAfter = pIn + nBytes;
321 if (g->iFakeDPI == 1) { // faking bi-level
322 while (pIn < pInAfter) {
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;
332 } else { // faking grayscale
333 while (pIn < pInAfter) {
337 gray = NTSC_LUMINANCE (rv, gv, bv);
338 *pOut++ = (BYTE)gray;
339 *pOut++ = (BYTE)gray;
340 *pOut++ = (BYTE)gray;
344 *pdwInputUsed = nBytes;
345 g->dwInNextPos += nBytes;
346 *pdwInputNextPos = g->dwInNextPos;
348 *pdwOutputUsed = nBytes;
349 *pdwOutputThisPos = g->dwOutNextPos;
350 g->dwOutNextPos += nBytes;
354 return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
357 return IP_FATAL_ERROR;
362 /*****************************************************************************\
364 * fakeMono_insertedData - client inserted into our output stream
366 \*****************************************************************************/
368 FUNC_STATUS WORD fakeMono_insertedData (
369 IP_XFORM_HANDLE hXform,
373 return IP_FATAL_ERROR; /* must never be called (can't insert data) */
378 /*****************************************************************************\
380 * fakeMono_newPage - Tells us to flush this page, and start a new page
382 \*****************************************************************************/
384 FUNC_STATUS WORD fakeMono_newPage (
385 IP_XFORM_HANDLE hXform)
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 */
394 return IP_FATAL_ERROR;
400 /*****************************************************************************\
402 * fakeMono_closeXform - Destroys this instance
404 \*****************************************************************************/
406 FUNC_STATUS WORD fakeMono_closeXform (IP_XFORM_HANDLE hXform)
410 HANDLE_TO_PTR (hXform, g);
413 IP_MEM_FREE (g); /* free memory for the instance */
418 return IP_FATAL_ERROR;
423 /*****************************************************************************\
425 * fakeMonoTbl - Jump-table for transform driver
427 \*****************************************************************************/
428 #ifdef EXPORT_TRANSFORM
429 __declspec (dllexport)
431 IP_XFORM_TBL fakeMonoTbl = {
433 fakeMono_setDefaultInputTraits,
434 fakeMono_setXformSpec,
435 fakeMono_getHeaderBufSize,
436 fakeMono_getActualTraits,
437 fakeMono_getActualBufSizes,
440 fakeMono_insertedData,
447 /*****************************************************************************\
449 * ipGetXformTable - Returns pointer to the jump table
451 \*****************************************************************************/
453 #ifdef EXPORT_TRANSFORM
454 EXPORT(WORD) ipGetXformTable (LPIP_XFORM_TBL pXform)
461 wRet = IP_FATAL_ERROR;