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: David Paschal (based on Mark Overton's "xskel" template). */
34 /******************************************************************************\
36 * xinvert.c - Inverts bilevel, grayscale, or color data.
38 ******************************************************************************
40 * Name of Global Jump-Table:
44 * Items in aXformInfo array passed into setXformSpec:
48 * Capabilities and Limitations:
50 * For 1-3 bpp, does a NOT operation (complements the bits).
51 * For >3 bpp, does a NEG operation (NEG plus 1).
53 * Default Input Traits, and Output Traits:
55 * Describe what you do with the default input traits, and how the
56 * output traits are determined.
58 * trait default input output
59 * ------------------- --------------------- ------------------------
60 * iPixelsPerRow * passed into output same as default input
61 * iBitsPerPixel * passed into output same as default input
62 * iComponentsPerPixel * passed into output same as default input
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 DWORD dwBytesPerRow; /* # of bytes in each row */
102 DWORD dwRowsDone; /* number of rows converted so far */
103 DWORD dwInNextPos; /* file pos for subsequent input */
104 DWORD dwOutNextPos; /* file pos for subsequent output */
105 DWORD dwAddToNot; /* 0=NOT, 1=NEG operation. */
106 DWORD dwValidChk; /* struct validity check value */
107 } INVERT_INST, *PINVERT_INST;
111 /*****************************************************************************\
113 * invert_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 invert_openXform (
125 IP_XFORM_HANDLE *pXform) /* out: returned handle */
129 INSURE (pXform != NULL);
130 IP_MEM_ALLOC (sizeof(INVERT_INST), g);
132 memset (g, 0, sizeof(INVERT_INST));
133 g->dwValidChk = CHECK_VALUE;
137 return IP_FATAL_ERROR;
142 /*****************************************************************************\
144 * invert_setDefaultInputTraits - Specifies default input image traits
146 *****************************************************************************
148 * The header of the file-type handled by the transform probably does
149 * not include *all* the image traits we'd like to know. Those not
150 * specified in the file-header are filled in from info provided by
153 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
155 \*****************************************************************************/
157 FUNC_STATUS WORD invert_setDefaultInputTraits (
158 IP_XFORM_HANDLE hXform, /* in: handle for xform */
159 PIP_IMAGE_TRAITS pTraits) /* in: default image traits */
163 HANDLE_TO_PTR (hXform, g);
165 /* insure that traits we care about are known */
166 INSURE (pTraits->iPixelsPerRow>0 && pTraits->iBitsPerPixel>0);
167 g->traits = *pTraits; /* a structure copy */
168 g->dwBytesPerRow = (g->traits.iPixelsPerRow*g->traits.iBitsPerPixel + 7) / 8;
169 if (pTraits->iBitsPerPixel>3) {
177 return IP_FATAL_ERROR;
182 /*****************************************************************************\
184 * invert_setXformSpec - Provides xform-specific information
186 \*****************************************************************************/
188 FUNC_STATUS WORD invert_setXformSpec (
189 IP_XFORM_HANDLE hXform, /* in: handle for xform */
190 DWORD_OR_PVOID aXformInfo[]) /* in: xform information */
194 HANDLE_TO_PTR (hXform, g);
196 /* Check your options in aXformInfo here, and save them.
197 * Use the INSURE macro like you'd use assert. INSURE jumps to
198 * fatal_error below if it fails.
204 return IP_FATAL_ERROR;
209 /*****************************************************************************\
211 * invert_getHeaderBufSize- Returns size of input buf needed to hold header
213 \*****************************************************************************/
215 FUNC_STATUS WORD invert_getHeaderBufSize (
216 IP_XFORM_HANDLE hXform, /* in: handle for xform */
217 DWORD *pdwInBufLen) /* out: buf size for parsing header */
219 /* since input is raw pixels, there is no header, so set it to zero */
226 /*****************************************************************************\
228 * invert_getActualTraits - Parses header, and returns input & output traits
230 \*****************************************************************************/
232 FUNC_STATUS WORD invert_getActualTraits (
233 IP_XFORM_HANDLE hXform, /* in: handle for xform */
234 DWORD dwInputAvail, /* in: # avail bytes in input buf */
235 PBYTE pbInputBuf, /* in: ptr to input buffer */
236 PDWORD pdwInputUsed, /* out: # bytes used from input buf */
237 PDWORD pdwInputNextPos,/* out: file-pos to read from next */
238 PIP_IMAGE_TRAITS pInTraits, /* out: input image traits */
239 PIP_IMAGE_TRAITS pOutTraits) /* out: output image traits */
243 HANDLE_TO_PTR (hXform, g);
245 /* Since there is no header, we'll report no usage of input */
247 *pdwInputNextPos = 0;
250 *pInTraits = g->traits; /* structure copies */
251 *pOutTraits = g->traits;
253 return IP_DONE | IP_READY_FOR_DATA;
256 return IP_FATAL_ERROR;
261 /****************************************************************************\
263 * invert_getActualBufSizes - Returns buf sizes needed for remainder of job
265 \****************************************************************************/
267 FUNC_STATUS WORD invert_getActualBufSizes (
268 IP_XFORM_HANDLE hXform, /* in: handle for xform */
269 PDWORD pdwMinInBufLen, /* out: min input buf size */
270 PDWORD pdwMinOutBufLen) /* out: min output buf size */
274 HANDLE_TO_PTR (hXform, g);
276 *pdwMinInBufLen = *pdwMinOutBufLen = g->dwBytesPerRow;
280 return IP_FATAL_ERROR;
285 /*****************************************************************************\
287 * invert_convert - Converts one row
289 \*****************************************************************************/
291 FUNC_STATUS WORD invert_convert (
292 IP_XFORM_HANDLE hXform,
293 DWORD dwInputAvail, /* in: # avail bytes in in-buf */
294 PBYTE pbInputBuf, /* in: ptr to in-buffer */
295 PDWORD pdwInputUsed, /* out: # bytes used from in-buf */
296 PDWORD pdwInputNextPos, /* out: file-pos to read from next */
297 DWORD dwOutputAvail, /* in: # avail bytes in out-buf */
298 PBYTE pbOutputBuf, /* in: ptr to out-buffer */
299 PDWORD pdwOutputUsed, /* out: # bytes written in out-buf */
300 PDWORD pdwOutputThisPos) /* out: file-pos to write the data */
306 HANDLE_TO_PTR (hXform, g);
308 /**** Check if we were told to flush ****/
310 if (pbInputBuf == NULL) {
311 PRINT (_T("invert_convert: Told to flush.\n"), 0, 0);
312 *pdwInputUsed = *pdwOutputUsed = 0;
313 *pdwInputNextPos = g->dwInNextPos;
314 *pdwOutputThisPos = g->dwOutNextPos;
318 /**** Output a Row ****/
320 nBytes = g->dwBytesPerRow;
321 INSURE (dwInputAvail >= (DWORD)nBytes );
322 INSURE (dwOutputAvail >= (DWORD)nBytes);
327 /* At this point, pIn is your input buffer, and pOut is your output buffer.
328 * Do whatever you are going to do here.
330 for (i=0;i<nBytes;i++) {
331 pOut[i]=~pIn[i]+g->dwAddToNot;
334 *pdwInputUsed = nBytes;
335 g->dwInNextPos += nBytes;
336 *pdwInputNextPos = g->dwInNextPos;
338 *pdwOutputUsed = nBytes;
339 *pdwOutputThisPos = g->dwOutNextPos;
340 g->dwOutNextPos += nBytes;
344 return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
347 return IP_FATAL_ERROR;
352 /*****************************************************************************\
354 * invert_insertedData - client inserted into our output stream
356 \*****************************************************************************/
358 FUNC_STATUS WORD invert_insertedData (
359 IP_XFORM_HANDLE hXform,
363 return IP_FATAL_ERROR; /* must never be called (can't insert data) */
368 /*****************************************************************************\
370 * invert_newPage - Tells us to flush this page, and start a new page
372 \*****************************************************************************/
374 FUNC_STATUS WORD invert_newPage (
375 IP_XFORM_HANDLE hXform)
379 HANDLE_TO_PTR (hXform, g);
380 /* todo: return fatal error if convert is called again? */
381 return IP_DONE; /* can't insert page-breaks, so ignore this call */
384 return IP_FATAL_ERROR;
390 /*****************************************************************************\
392 * invert_closeXform - Destroys this instance
394 \*****************************************************************************/
396 FUNC_STATUS WORD invert_closeXform (IP_XFORM_HANDLE hXform)
400 HANDLE_TO_PTR (hXform, g);
403 IP_MEM_FREE (g); /* free memory for the instance */
408 return IP_FATAL_ERROR;
413 /*****************************************************************************\
415 * invertTbl - Jump-table for transform driver
417 \*****************************************************************************/
418 #ifdef EXPORT_TRANSFORM
419 __declspec (dllexport)
421 IP_XFORM_TBL invertTbl = {
423 invert_setDefaultInputTraits,
425 invert_getHeaderBufSize,
426 invert_getActualTraits,
427 invert_getActualBufSizes,
437 /*****************************************************************************\
439 * ipGetXformTable - Returns pointer to the jump table
441 \*****************************************************************************/
443 #ifdef EXPORT_TRANSFORM
444 EXPORT(WORD) ipGetXformTable (LPIP_XFORM_TBL pXform)
454 wRet = IP_FATAL_ERROR;