Tizen 2.1 base
[platform/upstream/hplip.git] / ip / xinvert.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: David Paschal (based on Mark Overton's "xskel" template). */
33
34 /******************************************************************************\
35  *
36  * xinvert.c - Inverts bilevel, grayscale, or color data.
37  *
38  ******************************************************************************
39  *
40  * Name of Global Jump-Table:
41  *
42  *    invertTbl
43  *
44  * Items in aXformInfo array passed into setXformSpec:
45  *
46  *    None.
47  *
48  * Capabilities and Limitations:
49  *
50  *    For 1-3 bpp, does a NOT operation (complements the bits).
51  *    For >3 bpp, does a NEG operation (NEG plus 1).
52  *
53  * Default Input Traits, and Output Traits:
54  *
55  *    Describe what you do with the default input traits, and how the
56  *    output traits are determined.
57  *
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
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     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;
108
109
110
111 /*****************************************************************************\
112  *
113  * invert_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 invert_openXform (
125     IP_XFORM_HANDLE *pXform)   /* out: returned handle */
126 {
127     PINVERT_INST g;
128
129     INSURE (pXform != NULL);
130     IP_MEM_ALLOC (sizeof(INVERT_INST), g);
131     *pXform = g;
132     memset (g, 0, sizeof(INVERT_INST));
133     g->dwValidChk = CHECK_VALUE;
134     return IP_DONE;
135
136     fatal_error:
137     return IP_FATAL_ERROR;
138 }
139
140
141
142 /*****************************************************************************\
143  *
144  * invert_setDefaultInputTraits - Specifies default input image traits
145  *
146  *****************************************************************************
147  *
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
151  * this routine.
152  *
153  * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
154  *
155 \*****************************************************************************/
156
157 FUNC_STATUS WORD invert_setDefaultInputTraits (
158     IP_XFORM_HANDLE  hXform,     /* in: handle for xform */
159     PIP_IMAGE_TRAITS pTraits)    /* in: default image traits */
160 {
161     PINVERT_INST g;
162
163     HANDLE_TO_PTR (hXform, g);
164
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) {
170         g->dwAddToNot=1;
171     } else {
172         g->dwAddToNot=0;
173     }
174     return IP_DONE;
175
176     fatal_error:
177     return IP_FATAL_ERROR;
178 }
179
180
181
182 /*****************************************************************************\
183  *
184  * invert_setXformSpec - Provides xform-specific information
185  *
186 \*****************************************************************************/
187
188 FUNC_STATUS WORD invert_setXformSpec (
189     IP_XFORM_HANDLE hXform,         /* in: handle for xform */
190     DWORD_OR_PVOID  aXformInfo[])   /* in: xform information */
191 {
192     PINVERT_INST g;
193
194     HANDLE_TO_PTR (hXform, g);
195
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.
199      */
200
201     return IP_DONE;
202
203     fatal_error:
204     return IP_FATAL_ERROR;
205 }
206
207
208
209 /*****************************************************************************\
210  *
211  * invert_getHeaderBufSize- Returns size of input buf needed to hold header
212  *
213 \*****************************************************************************/
214
215 FUNC_STATUS WORD invert_getHeaderBufSize (
216     IP_XFORM_HANDLE  hXform,         /* in:  handle for xform */
217     DWORD           *pdwInBufLen)    /* out: buf size for parsing header */
218 {
219     /* since input is raw pixels, there is no header, so set it to zero */
220     *pdwInBufLen = 0;
221     return IP_DONE;
222 }
223
224
225
226 /*****************************************************************************\
227  *
228  * invert_getActualTraits - Parses header, and returns input & output traits
229  *
230 \*****************************************************************************/
231
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 */
240 {
241     PINVERT_INST g;
242
243     HANDLE_TO_PTR (hXform, g);
244
245     /* Since there is no header, we'll report no usage of input */
246     *pdwInputUsed    = 0;
247     *pdwInputNextPos = 0;
248     g->dwInNextPos   = 0;
249
250     *pInTraits  = g->traits;   /* structure copies */
251     *pOutTraits = g->traits;
252
253     return IP_DONE | IP_READY_FOR_DATA;
254
255     fatal_error:
256     return IP_FATAL_ERROR;
257 }
258
259
260
261 /****************************************************************************\
262  *
263  * invert_getActualBufSizes - Returns buf sizes needed for remainder of job
264  *
265 \****************************************************************************/
266
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 */
271 {
272     PINVERT_INST g;
273
274     HANDLE_TO_PTR (hXform, g);
275
276     *pdwMinInBufLen = *pdwMinOutBufLen = g->dwBytesPerRow;
277     return IP_DONE;
278
279     fatal_error:
280     return IP_FATAL_ERROR;
281 }
282
283
284
285 /*****************************************************************************\
286  *
287  * invert_convert - Converts one row
288  *
289 \*****************************************************************************/
290
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 */
301 {
302     PINVERT_INST g;
303     int       nBytes,i;
304     PBYTE     pIn, pOut;
305
306     HANDLE_TO_PTR (hXform, g);
307
308     /**** Check if we were told to flush ****/
309
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;
315         return IP_DONE;
316     }
317
318     /**** Output a Row ****/
319
320     nBytes = g->dwBytesPerRow;
321     INSURE (dwInputAvail  >= (DWORD)nBytes );
322     INSURE (dwOutputAvail >= (DWORD)nBytes);
323
324     pIn  = pbInputBuf;
325     pOut = pbOutputBuf;
326
327     /* At this point, pIn is your input buffer, and pOut is your output buffer.
328      * Do whatever you are going to do here.
329      */
330     for (i=0;i<nBytes;i++) {
331         pOut[i]=~pIn[i]+g->dwAddToNot;
332     }
333
334     *pdwInputUsed     = nBytes;
335     g->dwInNextPos   += nBytes;
336     *pdwInputNextPos  = g->dwInNextPos;
337
338     *pdwOutputUsed    = nBytes;
339     *pdwOutputThisPos = g->dwOutNextPos;
340     g->dwOutNextPos  += nBytes;
341
342     g->dwRowsDone += 1;
343
344     return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
345
346     fatal_error:
347     return IP_FATAL_ERROR;
348 }
349
350
351
352 /*****************************************************************************\
353  *
354  * invert_insertedData - client inserted into our output stream
355  *
356 \*****************************************************************************/
357
358 FUNC_STATUS WORD invert_insertedData (
359     IP_XFORM_HANDLE hXform,
360     DWORD           dwNumBytes)
361 {
362     fatalBreakPoint ();
363     return IP_FATAL_ERROR;   /* must never be called (can't insert data) */
364 }
365
366
367
368 /*****************************************************************************\
369  *
370  * invert_newPage - Tells us to flush this page, and start a new page
371  *
372 \*****************************************************************************/
373
374 FUNC_STATUS WORD invert_newPage (
375     IP_XFORM_HANDLE hXform)
376 {
377     PINVERT_INST g;
378
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 */
382
383     fatal_error:
384     return IP_FATAL_ERROR;
385
386 }
387
388
389
390 /*****************************************************************************\
391  *
392  * invert_closeXform - Destroys this instance
393  *
394 \*****************************************************************************/
395
396 FUNC_STATUS WORD invert_closeXform (IP_XFORM_HANDLE hXform)
397 {
398     PINVERT_INST g;
399
400     HANDLE_TO_PTR (hXform, g);
401
402     g->dwValidChk = 0;
403     IP_MEM_FREE (g);       /* free memory for the instance */
404
405     return IP_DONE;
406
407     fatal_error:
408     return IP_FATAL_ERROR;
409 }
410
411
412
413 /*****************************************************************************\
414  *
415  * invertTbl - Jump-table for transform driver
416  *
417 \*****************************************************************************/
418 #ifdef EXPORT_TRANSFORM
419 __declspec (dllexport)
420 #endif
421 IP_XFORM_TBL invertTbl = {
422     invert_openXform,
423     invert_setDefaultInputTraits,
424     invert_setXformSpec,
425     invert_getHeaderBufSize,
426     invert_getActualTraits,
427     invert_getActualBufSizes,
428     invert_convert,
429     invert_newPage,
430     invert_insertedData,
431     invert_closeXform
432 };
433
434 /* End of File */
435
436
437 /*****************************************************************************\
438  *
439  * ipGetXformTable - Returns pointer to the jump table
440  *
441 \*****************************************************************************/
442
443 #ifdef EXPORT_TRANSFORM
444 EXPORT(WORD) ipGetXformTable (LPIP_XFORM_TBL pXform)
445 {
446     WORD wRet = IP_DONE;
447
448     if (pXform)
449     {
450         *pXform = clrmapTbl;
451     }
452     else
453     {
454         wRet = IP_FATAL_ERROR;
455     }
456
457     return wRet;
458 }
459 #endif